diff --git a/adept/lpse2d/core/epw.py b/adept/lpse2d/core/epw.py index df539fd..0730484 100644 --- a/adept/lpse2d/core/epw.py +++ b/adept/lpse2d/core/epw.py @@ -1,64 +1,17 @@ from typing import Dict, Tuple +from functools import partial import diffrax import jax from jax import numpy as jnp import equinox as eqx import numpy as np -from theory import electrostatic +from adept.theory import electrostatic from adept.lpse2d.core.driver import Driver +from adept.lpse2d.core.trapper import ParticleTrapper -class ParticleTrapper(eqx.Module): - kx: np.ndarray - kax_sq: jax.Array - - model_kld: float - wis: jax.Array - norm_kld: jnp.float64 - norm_nuee: jnp.float64 - vph: jnp.float64 - fft_norm: float - dx: float - - def __init__(self, cfg, species="electron"): - self.kx = cfg["grid"]["kx"] - self.dx = cfg["grid"]["dx"] - self.kax_sq = cfg["grid"]["kx"][:, None] ** 2 + cfg["grid"]["ky"][None, :] ** 2 - table_wrs, table_wis, table_klds = electrostatic.get_complex_frequency_table( - 1024, cfg["terms"]["epw"]["kinetic real part"] - ) - all_ks = jnp.sqrt(self.kax_sq).flatten() - self.model_kld = cfg["terms"]["epw"]["trapping"]["kld"] - self.wis = jnp.interp(all_ks, table_klds, table_wis, left=0.0, right=0.0).reshape(self.kax_sq.shape) - self.norm_kld = (self.model_kld - 0.26) / 0.14 - self.norm_nuee = (jnp.log10(1.0e-7) + 7.0) / -4.0 - - this_wr = jnp.interp(self.model_kld, table_klds, table_wrs, left=1.0, right=table_wrs[-1]) - self.vph = this_wr / self.model_kld - self.fft_norm = cfg["grid"]["nx"] * cfg["grid"]["ny"] / 4.0 - # Make models - # if models is not None: - # self.nu_g_model = models["nu_g"] - # else: - # self.nu_g_model = lambda x: -32 - - def __call__(self, t, delta, args): - e = args["eh"] - ek = jnp.fft.fft2(e[..., 0]) / self.fft_norm - - # this is where a specific k is chosen for the growth rate and where the identity of this delta object is given - chosen_ek = jnp.interp(self.model_kld, self.kx, jnp.mean(jnp.abs(ek), axis=1)) - norm_e = (jnp.log10(chosen_ek + 1e-10) + 10.0) / -10.0 - func_inputs = jnp.stack([norm_e, self.norm_kld, self.norm_nuee], axis=-1) - growth_rates = 10 ** jnp.squeeze(3 * args["nu_g"](func_inputs)) - - return -self.vph * jnp.gradient(jnp.pad(delta, pad_width=1, mode="wrap"), axis=0)[ - 1:-1, 1:-1 - ] / self.dx + growth_rates * jnp.abs(jnp.fft.ifft2(ek * self.fft_norm * self.wis)) / (1.0 + delta**2.0) - - -class EPW2D(eqx.Module): +class SpectralPotential_old(eqx.Module): wp0: float ld_rates: jax.Array n0: float @@ -138,9 +91,9 @@ def calc_density_pert_step(self, nb: jax.Array, dn: jax.Array) -> jax.Array: return -1j / 2.0 * self.wp0 * (1.0 - nb / self.n0 - dn / self.n0) def _calc_div_(self, arr): - arrk = jnp.fft.fft2(arr) + arrk = jnp.fft.fft2(arr, axes=[0, 1]) divk = self.kx[:, None] * arrk[..., 0] + self.ky[None, :] * arrk[..., 1] - return jnp.fft.ifft2(divk) + return jnp.fft.ifft2(divk, axes=[0, 1]) def calc_tpd_source_step(self, phi: jax.Array, e0: jax.Array, nb: jax.Array, t: float) -> jax.Array: """ @@ -197,7 +150,7 @@ def update_delta(self, t, y, args): # return y["delta"] + self.dt * self.trapper(t, y["delta"], args) return diffrax.diffeqsolve( terms=diffrax.ODETerm(self.trapper), - solver=diffrax.Dopri8(), + solver=diffrax.Tsit5(), t0=t, t1=t + self.dt, max_steps=self.num_substeps, @@ -233,3 +186,271 @@ def __call__(self, t, y, args): ) return y + + +class SpectralPotential: + def __init__(self, cfg) -> None: + + self.kx = cfg["grid"]["kx"] + self.ky = cfg["grid"]["ky"] + self.k_sq = self.kx[:, None] ** 2 + self.ky[None, :] ** 2 + self.wp0 = cfg["units"]["derived"]["wp0"] + self.e = cfg["units"]["derived"]["e"] + self.me = cfg["units"]["derived"]["me"] + self.w0 = cfg["units"]["derived"]["w0"] + self.envelope_density = cfg["units"]["envelope density"] + self.one_over_ksq = cfg["grid"]["one_over_ksq"] + self.boundary_envelope = cfg["grid"]["absorbing_boundaries"] + self.dt = cfg["grid"]["dt"] + self.cfg = cfg + self.amp_key, self.phase_key = jax.random.split(jax.random.PRNGKey(np.random.randint(2**20)), 2) + self.low_pass_filter = np.where(np.sqrt(self.k_sq) < 2.0 / 3.0 * np.amax(self.kx), 1, 0) + zero_mask = cfg["grid"]["zero_mask"] + self.low_pass_filter = self.low_pass_filter * zero_mask + self.nx = cfg["grid"]["nx"] + self.ny = cfg["grid"]["ny"] + # self.step_tpd = partial( + # diffrax.diffeqsolve, + # terms=diffrax.ODETerm(self.tpd), + # solver=diffrax.Tsit5(), + # t0=0.0, + # t1=self.dt, + # dt0=self.dt, + # ) + self.tpd_const = 1j * self.e / (8 * self.wp0 * self.me) + + def calc_fields_from_phi(self, phi): + """ + Calculates ex(x, y) and ey(x, y) from phi. + + checked + + Args: + phi (jnp.array): phi(x, y) + + Returns: + ex_ey (jnp.array): Vector field e(x, y, dir) + """ + phi_k = jnp.fft.fft2(phi) + phi_k *= self.low_pass_filter + + ex_k = self.kx[:, None] * phi_k * self.low_pass_filter + ey_k = self.ky[None, :] * phi_k * self.low_pass_filter + return -1j * jnp.fft.ifft2(ex_k), -1j * jnp.fft.ifft2(ey_k) + + def calc_phi_from_fields(self, ex, ey): + """ + + checked + + """ + ex_k = jnp.fft.fft2(ex) + ey_k = jnp.fft.fft2(ey) + divE_k = 1j * (self.kx[:, None] * ex_k + self.ky[None, :] * ey_k) + + phi_k = divE_k * self.one_over_ksq + phi = jnp.fft.ifft2(phi_k * self.low_pass_filter) + + return phi + + def tpd(self, t, y, args): + """ + checked + + """ + E0 = args["E0"] # .view(jnp.complex128) + phi = y # .view(jnp.complex128) + _, ey = self.calc_fields_from_phi(phi) + + tpd1 = E0[..., 1] * jnp.conj(ey) + tpd1 = jnp.fft.ifft2(jnp.fft.fft2(tpd1) * self.low_pass_filter) + # tpd1 = E0_Ey + + divE_true = jnp.fft.ifft2(self.k_sq * jnp.fft.fft2(phi)) + E0_divE_k = jnp.fft.fft2(E0[..., 1] * jnp.conj(divE_true)) + tpd2 = 1j * self.ky[None, :] * self.one_over_ksq * E0_divE_k + tpd2 = jnp.fft.ifft2(tpd2 * self.low_pass_filter) + + total_tpd = self.tpd_const * jnp.exp(-1j * (self.w0 - 2 * self.wp0) * t) * (tpd1 + tpd2) + + dphi = total_tpd # .view(jnp.float64) + + return dphi + + def calc_tpd1(self, t, y, args): + E0 = args["E0"] + phi = y + + _, ey = self.calc_fields_from_phi(phi) + + tpd1 = E0[..., 1] * jnp.conj(ey) + return self.tpd_const * tpd1 + + def calc_tpd2(self, t, y, args): + phi = y + E0 = args["E0"] + + divE_true = jnp.fft.ifft2(self.k_sq * jnp.fft.fft2(phi)) + E0_divE_k = jnp.fft.fft2(E0[..., 1] * jnp.conj(divE_true)) + + tpd2 = 1j * self.ky[None, :] * self.one_over_ksq * E0_divE_k + tpd2 = jnp.fft.ifft2(tpd2) + return self.tpd_const * tpd2 + + def get_noise(self): + random_amps = 1000.0 # jax.random.uniform(self.amp_key, (self.nx, self.ny)) + random_phases = 2 * np.pi * jax.random.uniform(self.phase_key, (self.nx, self.ny)) + return jnp.fft.ifft2(random_amps * jnp.exp(1j * random_phases) * self.low_pass_filter) + + def __call__(self, t, y, args): + phi = y["epw"] + E0 = y["E0"] + background_density = y["background_density"] + vte_sq = y["vte_sq"] + + if self.cfg["terms"]["epw"]["linear"]: + # linear propagation + phi = jnp.fft.ifft2(jnp.fft.fft2(phi) * jnp.exp(-1j * 1.5 * vte_sq[0, 0] / self.wp0 * self.k_sq * self.dt)) + + # tpd + if self.cfg["terms"]["epw"]["source"]["tpd"]: + phi = phi + self.dt * self.tpd(t, phi, args={"E0": E0}) + + # density gradient + if self.cfg["terms"]["epw"]["density_gradient"]: + ex, ey = self.calc_fields_from_phi(phi) + ex *= jnp.exp(-1j * self.wp0 / 2.0 * (1 - background_density / self.envelope_density) * self.dt) + ey *= jnp.exp(-1j * self.wp0 / 2.0 * (1 - background_density / self.envelope_density) * self.dt) + phi = self.calc_phi_from_fields(ex, ey) + + if self.cfg["terms"]["epw"]["source"]["noise"]: + phi += self.dt * self.get_noise() + + return phi + + +class FDChargeDensity: + def __init__(self, cfg): + self.cfg = cfg + self.wp0 = cfg["units"]["derived"]["wp0"] + self.envelope_density = cfg["units"]["envelope density"] + self.kx = cfg["grid"]["kx"] + self.ky = cfg["grid"]["ky"] + self.dx = cfg["grid"]["dx_norm"] + self.dy = cfg["grid"]["dy_norm"] + self.e = cfg["units"]["derived"]["e"] + self.me = cfg["units"]["derived"]["me"] + self.w0 = cfg["units"]["derived"]["w0"] + self.dt = cfg["grid"]["dt"] + + def calc_fields_from_divE(self, divE): + """ + Calculates ex(x, y) and ey(x, y) from divE. + + Args: + divE (jnp.array): divE(x, y) + + Returns: + ex_ey (jnp.array): Vector field e(x, y, dir) + """ + phi = jnp.fft.fft2(divE) + + ex_k = self.cfg["grid"]["kx"][:, None] * phi + ey_k = self.cfg["grid"]["ky"][None, :] * phi + return -1j * jnp.concatenate([jnp.fft.ifft2(ex_k)[..., None], jnp.fft.ifft2(ey_k)[..., None]], axis=-1) + + def calc_divE_from_fields(self, ex_ey): + ex_k = jnp.fft.fft2(ex_ey[..., 0]) + ey_k = jnp.fft.fft2(ex_ey[..., 1]) + divE_k = 1j * (self.kx[:, None] * ex_k + self.ky[None, :] * ey_k) + return jnp.fft.ifft2(divE_k) + + def linear_propagate(self, divE, vte_sq, background_density): + padded_divE = jnp.pad(divE, ((1, 1), (1, 1)), mode="wrap") + d_divE = ( + 1.5 + * 1j + * vte_sq[0, 0] + / self.wp0 + * ( + (padded_divE[2:, 1:-1] - 2 * padded_divE[1:-1, 1:-1] + padded_divE[:-2, 1:-1]) / self.dx**2 + + (padded_divE[1:-1, 2:] - 2 * padded_divE[1:-1, 1:-1] + padded_divE[1:-1, :-2]) / self.dy**2 + ) + ) + d_divE -= 0.5 * 1j * self.wp0 * (background_density / self.envelope_density - 1) * divE + return d_divE + + def tpd(self, t, E0, divE, ey): + E0_Ey = E0[..., 1] * jnp.conj(ey) + E0_rho = E0[..., 1] * jnp.conj(divE) + padded_E0_rho = jnp.pad(E0_rho, ((1, 1), (1, 1)), mode="wrap") + padded_E0_Ey = jnp.pad(E0_Ey, ((1, 1), (1, 1)), mode="wrap") + tpd = ( + -1j + * self.e + / (8 * self.wp0 * self.me) + * jnp.exp(-1j * (self.w0 - 2 * self.wp0) * t) + * ( + (padded_E0_Ey[2:, 1:-1] - padded_E0_Ey[1:-1, 1:-1] + padded_E0_Ey[:-2, 1:-1]) / self.dx**2.0 + + (padded_E0_Ey[1:-1, 2:] - padded_E0_Ey[1:-1, 1:-1] + padded_E0_Ey[1:-1, :-2]) / self.dy**2.0 + - (padded_E0_rho[1:-1, 2:] - padded_E0_rho[1:-1, :-2]) / self.dy / 2.0 + ) + ) + + return tpd + + def density_gradient(self, ex, background_density): + grad_n = jnp.gradient(background_density, self.dx, axis=0) / self.envelope_density + return -0.5 * 1j * self.wp0 * grad_n * ex + + def single_step(self, t, y, args) -> jnp.array: + """ + Steps the epw forward in time in the form of a divE equation + This is a finite-difference based approach. + All of this mostly happens in real space. + + Args: + t (float): time + y (jnp.array): divE(x,y) + args (Dict[str, jnp.array]): additional arguments + + Returns: + divE (jnp.array]: updated divE(x,y) + + """ + + # calculate ex and ey from divE + ex_ey = self.calc_fields_from_divE(y) + + # iaw source + + # apply boundary damping to e fields + # ex_ey *= self.cfg["grid"]["absorbing_boundaries"][..., None] + + # convert fields back to divE + # divE = self.calc_divE_from_fields(ex_ey) + + divE = y + # charge density linear update + ddivE = self.linear_propagate(divE=divE, vte_sq=args["vte_sq"], background_density=args["background_density"]) + + # SRS source term + + # TPD source term + if self.cfg["terms"]["epw"]["source"]["tpd"]: + ddivE += self.tpd(t=t, E0=args["E0"], divE=divE, ey=ex_ey[..., 1]) + + # density gradient term + if self.cfg["terms"]["epw"]["density_gradient"]: + ddivE += self.density_gradient(ex_ey[..., 0], background_density=args["background_density"]) + + return ddivE + + def __call__(self, t, y, args): + args = {"E0": y["E0"], "background_density": y["background_density"], "vte_sq": y["vte_sq"]} + divE = y["div_E"] + + divE += self.dt * jnp.real(self.single_step(t, divE, args)) + divE += 1j * self.dt * jnp.imag(self.single_step(t + self.dt * 0.5, divE, args)) + + return divE diff --git a/adept/lpse2d/core/integrator.py b/adept/lpse2d/core/integrator.py index 352b42a..93d5b6e 100644 --- a/adept/lpse2d/core/integrator.py +++ b/adept/lpse2d/core/integrator.py @@ -1,39 +1,40 @@ from typing import Dict, List from jax import numpy as jnp +import numpy as np import equinox as eqx -import diffrax -from adept.lpse2d.core import epw +from adept.lpse2d.core import epw, laser +from adept.tf1d.pushers import get_envelope -class Stepper(diffrax.Euler): - def step(self, terms, t0, t1, y0, args, solver_state, made_jump): - del solver_state, made_jump - y1 = terms.vf(t0, y0, args) - dense_info = dict(y0=y0, y1=y1) - return y1, None, dense_info, None, diffrax.RESULTS.successful - - -class VectorField(eqx.Module): +class SplitStep: """ This class contains the function that updates the state All the pushers are chosen and initialized here and a single time-step is defined here. + Note that EPW can be either the charge density (div E) or the potential + :param cfg: :return: """ - cfg: Dict - epw: eqx.Module - complex_state_vars: List - def __init__(self, cfg): super().__init__() self.cfg = cfg - self.epw = epw.EPW2D(cfg) - self.complex_state_vars = ["e0", "phi"] + self.dt = cfg["grid"]["dt"] + self.wp0 = cfg["units"]["derived"]["wp0"] + # self.epw = epw.FDChargeDensity(cfg) + self.epw = epw.SpectralPotential(cfg) + self.light = laser.Light(cfg) + self.complex_state_vars = ["E0", "epw"] + self.boundary_envelope = cfg["grid"]["absorbing_boundaries"] + self.one_over_ksq = cfg["grid"]["one_over_ksq"] + self.zero_mask = cfg["grid"]["zero_mask"] + self.low_pass_filter = cfg["grid"]["low_pass_filter"] + + self.nu_coll = cfg["units"]["derived"]["nu_coll"] def unpack_y(self, y): new_y = {} @@ -44,11 +45,60 @@ def unpack_y(self, y): new_y[k] = y[k].view(jnp.float64) return new_y - def __call__(self, t, y, args): - new_y = self.epw(t, self.unpack_y(y), args) - + def pack_y(self, y, new_y): for k in y.keys(): y[k] = y[k].view(jnp.float64) new_y[k] = new_y[k].view(jnp.float64) + return y, new_y + + def light_split_step(self, t, y, args): + t_coeff = get_envelope(0.03, 0.03, 0.1, 100.0, t) + y["E0"] = self.boundary_envelope[..., None] * t_coeff * self.light.laser_update(t, y, args["E0"]) + + # if self.cfg["terms"]["light"]["update"]: + # y["E0"] = y["E0"] + self.dt * jnp.real(k1_E0) + + # t_coeff = get_envelope(0.1, 0.1, 0.2, 100.0, t + 0.5 * self.dt) + # y["E0"] = t_coeff * self.light.laser_update(t + 0.5 * self.dt, y, args["E0"]) + # if self.cfg["terms"]["light"]["update"]: + # y["E0"] = y["E0"] + 1j * self.dt * jnp.imag(k1_E0) + + return y + + def landau_damping(self, epw, vte_sq): + gammaLandauEpw = ( + np.sqrt(np.pi / 8) + * self.wp0**4 + * self.one_over_ksq**1.5 + / (vte_sq**1.5) + * jnp.exp(-self.wp0**2.0 * self.one_over_ksq / (2 * vte_sq)) + ) + + return jnp.fft.ifft2(jnp.fft.fft2(epw) * jnp.exp(-(gammaLandauEpw + self.nu_coll) * self.dt)) + + def __call__(self, t, y, args): + # unpack y into complex128 + new_y = self.unpack_y(y) + + # split step + new_y = self.light_split_step(t, new_y, args["drivers"]) + new_y["epw"] = self.epw(t, new_y, args) + + # landau and collisional damping + new_y["epw"] = self.landau_damping(epw=new_y["epw"], vte_sq=y["vte_sq"]) + + new_y["epw"] = jnp.fft.ifft2(self.zero_mask * jnp.fft.fft2(new_y["epw"])) + + # boundary damping + ex, ey = self.epw.calc_fields_from_phi(new_y["epw"]) + ex = ex * self.boundary_envelope + ey = ey * self.boundary_envelope + new_y["epw"] = self.epw.calc_phi_from_fields(ex, ey) + new_y["epw"] = jnp.fft.ifft2(self.zero_mask * self.low_pass_filter * jnp.fft.fft2(new_y["epw"])) + # new_y["epw"] = new_y["epw"] * self.boundary_envelope + + # pack y into float64 + y, new_y = self.pack_y(y, new_y) + return new_y diff --git a/adept/lpse2d/core/laser.py b/adept/lpse2d/core/laser.py new file mode 100644 index 0000000..dc464e9 --- /dev/null +++ b/adept/lpse2d/core/laser.py @@ -0,0 +1,37 @@ +from typing import Dict, Tuple +from jax import numpy as jnp +import numpy as np + + +class Light: + def __init__(self, cfg) -> None: + self.cfg = cfg + self.E0_source = cfg["units"]["derived"]["E0_source"] + self.c = cfg["units"]["derived"]["c"] + self.w0 = cfg["units"]["derived"]["w0"] + self.dE0x = jnp.zeros((cfg["grid"]["nx"], cfg["grid"]["ny"])) + self.x = cfg["grid"]["x"] + + def laser_update(self, t: float, y: jnp.ndarray, args: Dict) -> Tuple[jnp.ndarray, jnp.ndarray]: + """ + This function updates the laser field at time t + + :param t: time + :param y: state variables + :return: updated laser field + """ + # if self.cfg["laser"]["time"] == "static": + wpe = self.w0 * jnp.sqrt(y["background_density"])[None] + k0 = self.w0 / self.c * jnp.sqrt((1 + 0j + args["delta_omega"][:, None, None]) ** 2 - wpe**2 / self.w0**2) + E0_static = ( + (1 + 0j - wpe**2.0 / (self.w0 * (1 + args["delta_omega"][:, None, None])) ** 2) ** -0.25 + * self.E0_source + * args["amplitudes"][:, None, None] + * jnp.exp(1j * k0 * self.x[None, :, None] + 1j * args["initial_phase"][:, None, None]) + ) + dE0y = E0_static * jnp.exp(-1j * args["delta_omega"][:, None, None] * self.w0 * t) + E0 = jnp.stack([self.dE0x, jnp.sum(dE0y, axis=0)], axis=-1) + # else: + # raise NotImplementedError + + return E0 diff --git a/adept/lpse2d/core/trapper.py b/adept/lpse2d/core/trapper.py new file mode 100644 index 0000000..b4e3f3c --- /dev/null +++ b/adept/lpse2d/core/trapper.py @@ -0,0 +1,52 @@ +import numpy as np +from jax import numpy as jnp, Array +import equinox as eqx +from adept.theory import electrostatic + + +class ParticleTrapper(eqx.Module): + kx: np.ndarray + kax_sq: Array + model_kld: float + wis: Array + norm_kld: jnp.float64 + norm_nuee: jnp.float64 + vph: jnp.float64 + fft_norm: float + dx: float + + def __init__(self, cfg, species="electron"): + self.kx = cfg["grid"]["kx"] + self.dx = cfg["grid"]["dx"] + self.kax_sq = cfg["grid"]["kx"][:, None] ** 2 + cfg["grid"]["ky"][None, :] ** 2 + table_wrs, table_wis, table_klds = electrostatic.get_complex_frequency_table( + 1024, cfg["terms"]["epw"]["kinetic real part"] + ) + all_ks = jnp.sqrt(self.kax_sq).flatten() + self.model_kld = cfg["terms"]["epw"]["trapping"]["kld"] + self.wis = jnp.interp(all_ks, table_klds, table_wis, left=0.0, right=0.0).reshape(self.kax_sq.shape) + self.norm_kld = (self.model_kld - 0.26) / 0.14 + self.norm_nuee = (jnp.log10(1.0e-7) + 7.0) / -4.0 + + this_wr = jnp.interp(self.model_kld, table_klds, table_wrs, left=1.0, right=table_wrs[-1]) + self.vph = this_wr / self.model_kld + self.fft_norm = cfg["grid"]["nx"] * cfg["grid"]["ny"] / 4.0 + # Make models + # if models is not None: + # self.nu_g_model = models["nu_g"] + # else: + # self.nu_g_model = lambda x: -32 + + def __call__(self, t, delta, args): + e = args["eh"] + ek = jnp.fft.fft2(e[..., 0]) / self.fft_norm + + # this is where a specific k is chosen for the growth rate and where the identity of this delta object is given + chosen_ek = jnp.interp(self.model_kld, self.kx, jnp.mean(jnp.abs(ek), axis=1)) + norm_e = (jnp.log10(chosen_ek + 1e-10) + 10.0) / -10.0 + func_inputs = jnp.stack([norm_e, self.norm_kld, self.norm_nuee], axis=-1) + growth_rates = 10 ** jnp.squeeze(3 * args["nu_g"](func_inputs)) + + return -self.vph * jnp.gradient(jnp.pad(delta, pad_width=1, mode="wrap"), axis=0)[ + 1:-1, 1:-1 + ] / self.dx + growth_rates * jnp.abs(jnp.fft.ifft2(ek * self.fft_norm * self.wis)) / (1.0 + delta**2.0) diff --git a/adept/lpse2d/helpers.py b/adept/lpse2d/helpers.py index ca5cf8e..2c999e9 100644 --- a/adept/lpse2d/helpers.py +++ b/adept/lpse2d/helpers.py @@ -2,73 +2,148 @@ from typing import Dict, Callable, Tuple, List from collections import defaultdict - import matplotlib.pyplot as plt -import jax, pint, yaml +import yaml, mlflow from jax import numpy as jnp import numpy as np -from scipy import constants import equinox as eqx -from diffrax import ODETerm + import xarray as xr -from plasmapy.formulary.collisions.frequencies import fundamental_electron_collision_freq +from astropy.units import Quantity as _Q + +from adept.lpse2d import nn +from adept.lpse2d.run_fns import get_run_fn -from adept.lpse2d.core import integrator, driver from adept.tf1d.pushers import get_envelope def write_units(cfg, td): - ureg = pint.UnitRegistry() - _Q = ureg.Quantity - - n0 = _Q(cfg["units"]["normalizing density"]).to("1/cc") - T0 = _Q(cfg["units"]["normalizing temperature"]).to("eV") - - wp0 = np.sqrt(n0 * ureg.e**2.0 / (ureg.m_e * ureg.epsilon_0)).to("rad/s") - tp0 = (1 / wp0).to("fs") + timeScale = 1e-12 # cgs (ps) + spatialScale = 1e-4 # cgs (um) + velocityScale = spatialScale / timeScale + massScale = 1 + chargeScale = spatialScale ** (3 / 2) * massScale ** (1 / 2) / timeScale + fieldScale = massScale ** (1 / 2) / spatialScale ** (1 / 2) / timeScale + # forceScale = massScale * spatialScale/timeScale^2 + + Te = _Q(cfg["units"]["reference electron temperature"]).to("keV").value + Ti = _Q(cfg["units"]["reference ion temperature"]).to("keV").value + Z = cfg["units"]["ionization state"] + A = cfg["units"]["atomic number"] + lam0 = _Q(cfg["units"]["laser wavelength"]).to("um").value + I0 = _Q(cfg["units"]["laser intensity"]).to("W/cm^2").value + envelopeDensity = cfg["units"]["envelope density"] + + # Scaled constants + c_cgs = 2.99792458e10 + me_cgs = 9.10938291e-28 + mp_cgs = 1.6726219e-24 + e_cgs = 4.8032068e-10 + c = c_cgs / velocityScale + me = me_cgs / massScale + mi = mp_cgs * A / massScale + e = e_cgs / chargeScale + w0 = 2 * np.pi * c / lam0 # 1/ps + wp0 = w0 * np.sqrt(envelopeDensity) + w1 = w0 - wp0 + # nc = (w0*1e12)^2 * me / (4*pi*e^2) * (1e-4)^3 + vte = c * np.sqrt(Te / 511) + vte_sq = vte**2 + cs = c * np.sqrt((Z * Te + 3 * Ti) / (A * 511 * 1836)) + + # nu_sideloss = 1e-1 + + # nu_ei = calc_nuei(ne, Te, Z, ni, Ti) + # nu_ee = calc_nuee(ne, Te) + + nc = w0**2 * me / (4 * np.pi * e**2) + + E0_source = np.sqrt(8 * np.pi * I0 * 1e7 / c_cgs) / fieldScale + + ne_cc = nc * envelopeDensity * 1e4**3 + Te_eV = Te * 1000 + + coulomb_log = ( + 23.0 - jnp.log(jnp.sqrt(ne_cc) * Z / Te_eV**1.5) + if Te_eV < 10 * Z**2 + else 24.0 - jnp.log(jnp.sqrt(ne_cc) / Te_eV) + ) + fract = 1 + Zbar = Z * fract + ni = fract * ne_cc / Zbar + + # logLambda_ei = jnp.zeros(len(Z)) + # for iZ in range(len(Z)): + if cfg["terms"]["epw"]["damping"]["collisions"]: + if Te_eV < 0.01 * Z**2: + logLambda_ei = 22.8487 - jnp.log(jnp.sqrt(ne_cc) * Z / (Te * 1000) ** (3 / 2)) + elif Te_eV > 0.01 * Z**2: + logLambda_ei = 24 - jnp.log(jnp.sqrt(ne_cc) / (Te * 1000)) + + e_sq = 510.9896 * 2.8179e-13 + this_me = 510.9896 / 2.99792458e10**2 + nu_coll = ( + float( + (4 * np.sqrt(2 * np.pi) / 3 * e_sq**2 / np.sqrt(this_me) * Z**2 * ni * logLambda_ei / Te**1.5) + / 2 + * timeScale + ) + * cfg["terms"]["epw"]["damping"]["collisions"] + ) + else: + nu_coll = 1e-4 # nu_ee + nu_ei + nu_sideloss + + gradient_scale_length = _Q(cfg["density"]["gradient scale length"]).to("um").value + I_thresh = calc_threshold_intensity(Te, Ln=gradient_scale_length, w0=w0) + # for k in ["delta_omega", "initial_phase", "amplitudes"]: + + # Derived units + cfg["units"]["derived"] = { + "c": c, + "me": me, + "mi": mi, + "e": e, + "w0": w0, + "wp0": wp0, + "w1": w1, + "vte": vte, + "vte_sq": vte_sq, + "cs": cs, + "nc": nc, + "nu_coll": nu_coll, + "I_thresh": I_thresh, + "E0_source": E0_source, + "timeScale": timeScale, + "spatialScale": spatialScale, + "velocityScale": velocityScale, + "massScale": massScale, + "chargeScale": chargeScale, + "fieldScale": fieldScale, + } - v0 = np.sqrt(2.0 * T0 / ureg.m_e).to("m/s") - x0 = (v0 / wp0).to("nm") - c_light = _Q(1.0 * ureg.c).to("m/s") / v0 - beta = (v0 / ureg.c).to("dimensionless") + with open(os.path.join(td, "units.yaml"), "w") as fi: + yaml.dump({k: str(v) for k, v in cfg["units"]["derived"].items()}, fi) - box_length = ((cfg["grid"]["xmax"] - cfg["grid"]["xmin"]) * x0).to("microns") - if "ymax" in cfg["grid"].keys(): - box_width = ((cfg["grid"]["ymax"] - cfg["grid"]["ymin"]) * x0).to("microns") - else: - box_width = "inf" - sim_duration = (cfg["grid"]["tmax"] * tp0).to("ps") + return cfg - # collisions - logLambda_ee = 23.5 - np.log(n0.magnitude**0.5 / T0.magnitude**-1.25) - logLambda_ee -= (1e-5 + (np.log(T0.magnitude) - 2) ** 2.0 / 16) ** 0.5 - nuee = _Q(2.91e-6 * n0.magnitude * logLambda_ee / T0.magnitude**1.5, "Hz") - nuee_norm = nuee / wp0 - all_quantities = { - "wp0": wp0, - "tp0": tp0, - "n0": n0, - "v0": v0, - "T0": T0, - "c_light": c_light, - "beta": beta, - "x0": x0, - "nuee": nuee, - "logLambda_ee": logLambda_ee, - "box_length": box_length, - "box_width": box_width, - "sim_duration": sim_duration, - } +def calc_threshold_intensity(Te, Ln, w0): + """ + Calculate the TPD threshold intensity - cfg["units"]["derived"] = all_quantities + :param Te: + :return: intensity + """ - cfg["grid"]["beta"] = beta.magnitude + c = 2.99792458e10 + me_keV = 510.998946 # keV/c^2 + me_cgs = 9.10938291e-28 + e = 4.8032068e-10 - with open(os.path.join(td, "units.yaml"), "w") as fi: - yaml.dump({k: str(v) for k, v in all_quantities.items()}, fi) + vte = np.sqrt(Te / me_keV) * c + I_threshold = 4 * 4.134 * 1 / (8 * np.pi) * (me_cgs * c / e) ** 2 * w0 * vte**2 / (Ln / 100) * 1e-7 - return cfg + return I_threshold def get_derived_quantities(cfg: Dict) -> Dict: @@ -82,10 +157,38 @@ def get_derived_quantities(cfg: Dict) -> Dict: """ cfg_grid = cfg["grid"] - cfg_grid["dx"] = cfg_grid["xmax"] / cfg_grid["nx"] - cfg_grid["dy"] = cfg_grid["ymax"] / cfg_grid["ny"] + # cfg_grid["xmax"] = _Q(cfg_grid["xmax"]).to("um").value + # cfg_grid["xmin"] = _Q(cfg_grid["xmin"]).to("um").value + L = _Q(cfg["density"]["gradient scale length"]).to("um").value + nmax = cfg["density"]["max"] + nmin = cfg["density"]["min"] + Lgrid = L / 0.25 * (nmax - nmin) + + print("Ignoring xmax and xmin and using the density gradient scale length to set the grid size") + print("Grid size = L / 0.25 * (nmax - nmin) = ", Lgrid, "um") + cfg_grid["xmax"] = Lgrid + cfg_grid["xmin"] = 0.0 + + if "x" in cfg["save"]: + cfg["save"]["x"]["xmax"] = cfg_grid["xmax"] + + cfg_grid["ymax"] = _Q(cfg_grid["ymax"]).to("um").value + cfg_grid["ymin"] = _Q(cfg_grid["ymin"]).to("um").value + cfg_grid["dx"] = _Q(cfg_grid["dx"]).to("um").value + + cfg_grid["nx"] = int(cfg_grid["xmax"] / cfg_grid["dx"]) + 1 + # cfg_grid["dx"] = cfg_grid["xmax"] / cfg_grid["nx"] + cfg_grid["dy"] = cfg_grid["dx"] # cfg_grid["ymax"] / cfg_grid["ny"] + cfg_grid["ny"] = int(cfg_grid["ymax"] / cfg_grid["dy"]) + 1 + + # midpt = (cfg_grid["xmax"] + cfg_grid["xmin"]) / 2 + # max_density = cfg["density"]["val at center"] + (cfg["grid"]["xmax"] - midpt) / L + + norm_n_max = np.abs(nmax / cfg["units"]["envelope density"] - 1) # cfg_grid["dt"] = 0.05 * cfg_grid["dx"] + cfg_grid["dt"] = _Q(cfg_grid["dt"]).to("ps").value + cfg_grid["tmax"] = _Q(cfg_grid["tmax"]).to("ps").value cfg_grid["nt"] = int(cfg_grid["tmax"] / cfg_grid["dt"] + 1) cfg_grid["tmax"] = cfg_grid["dt"] * cfg_grid["nt"] @@ -102,19 +205,6 @@ def get_derived_quantities(cfg: Dict) -> Dict: return cfg -def get_save_quantities(cfg: Dict) -> Dict: - """ - This function updates the config with the quantities required for the diagnostics and saving routines - - :param cfg: - :return: - """ - # cfg["save"]["func"] = {**cfg["save"]["func"], **{"callable": get_save_func(cfg)}} - cfg["save"]["t"]["ax"] = jnp.linspace(cfg["save"]["t"]["tmin"], cfg["save"]["t"]["tmax"], cfg["save"]["t"]["nt"]) - - return cfg - - def get_solver_quantities(cfg: Dict) -> Dict: """ This function just updates the config with the derived quantities that are arrays @@ -127,20 +217,27 @@ def get_solver_quantities(cfg: Dict) -> Dict: cfg_grid = cfg["grid"] + Lx = cfg_grid["xmax"] - cfg_grid["xmin"] + Ly = cfg_grid["ymax"] - cfg_grid["ymin"] + cfg_grid = { **cfg_grid, **{ "x": jnp.linspace( - cfg_grid["xmin"] + cfg_grid["dx"] / 2, cfg_grid["xmax"] - cfg_grid["dx"] / 2, cfg_grid["nx"] + cfg_grid["xmin"] + cfg_grid["dx"] / 2, + cfg_grid["xmax"] - cfg_grid["dx"] / 2, + cfg_grid["nx"], ), "y": jnp.linspace( - cfg_grid["ymin"] + cfg_grid["dy"] / 2, cfg_grid["ymax"] - cfg_grid["dy"] / 2, cfg_grid["ny"] + cfg_grid["ymin"] + cfg_grid["dy"] / 2, + cfg_grid["ymax"] - cfg_grid["dy"] / 2, + cfg_grid["ny"], ), "t": jnp.linspace(0, cfg_grid["tmax"], cfg_grid["nt"]), - "kx": jnp.fft.fftfreq(cfg_grid["nx"], d=cfg_grid["dx"]) * 2.0 * np.pi, - "kxr": jnp.fft.rfftfreq(cfg_grid["nx"], d=cfg_grid["dx"]) * 2.0 * np.pi, - "ky": jnp.fft.fftfreq(cfg_grid["ny"], d=cfg_grid["dy"]) * 2.0 * np.pi, - "kyr": jnp.fft.rfftfreq(cfg_grid["ny"], d=cfg_grid["dy"]) * 2.0 * np.pi, + "kx": jnp.fft.fftfreq(cfg_grid["nx"], d=cfg_grid["dx"] / 2.0 / np.pi), + "kxr": jnp.fft.rfftfreq(cfg_grid["nx"], d=cfg_grid["dx"] / 2.0 / np.pi), + "ky": jnp.fft.fftfreq(cfg_grid["ny"], d=cfg_grid["dy"] / 2.0 / np.pi), + "kyr": jnp.fft.rfftfreq(cfg_grid["ny"], d=cfg_grid["dy"] / 2.0 / np.pi), }, } @@ -164,22 +261,43 @@ def get_solver_quantities(cfg: Dict) -> Dict: one_over_ksq[0, 0] = 0.0 cfg_grid["one_over_ksq"] = jnp.array(one_over_ksq) + boundary_width = _Q(cfg_grid["boundary_width"]).to("um").value + rise = boundary_width / 5 + if cfg["terms"]["epw"]["boundary"]["x"] == "absorbing": - envelope_x = driver.get_envelope(50.0, 50.0, 300.0, cfg["grid"]["xmax"] - 300.0, cfg_grid["x"])[:, None] + left = cfg["grid"]["xmin"] + boundary_width + right = cfg["grid"]["xmax"] - boundary_width + + envelope_x = get_envelope(rise, rise, left, right, cfg_grid["x"])[:, None] else: envelope_x = np.ones((cfg_grid["nx"], cfg_grid["ny"])) if cfg["terms"]["epw"]["boundary"]["y"] == "absorbing": - envelope_y = driver.get_envelope(50.0, 50.0, 300.0, cfg["grid"]["ymax"] - 300.0, cfg_grid["y"])[None, :] + left = cfg["grid"]["ymin"] + boundary_width + right = cfg["grid"]["ymax"] - boundary_width + envelope_y = get_envelope(rise, rise, left, right, cfg_grid["y"])[None, :] else: envelope_y = np.ones((cfg_grid["nx"], cfg_grid["ny"])) - cfg_grid["absorbing_boundaries"] = np.exp(-cfg_grid["dt"] * (1.0 - envelope_x * envelope_y)) + cfg_grid["absorbing_boundaries"] = np.exp( + -float(cfg_grid["boundary_abs_coeff"]) * cfg_grid["dt"] * (1.0 - envelope_x * envelope_y) + ) + + cfg_grid["zero_mask"] = ( + np.where(cfg_grid["kx"][:, None] * cfg_grid["ky"][None, :] == 0, 0, 1) if cfg["terms"]["zero_mask"] else 1 + ) + # sqrt(kx**2 + ky**2) < 2/3 kmax + cfg_grid["low_pass_filter"] = np.where( + np.sqrt(cfg_grid["kx"][:, None] ** 2 + cfg_grid["ky"][None, :] ** 2) + < cfg_grid["low_pass_filter"] * cfg_grid["kx"].max(), + 1, + 0, + ) return cfg_grid -def init_state(cfg: Dict, td=None) -> Dict: +def init_state(cfg: Dict, td=None) -> Tuple[Dict, Dict]: """ This function initializes the state for the PDE solve @@ -192,20 +310,6 @@ def init_state(cfg: Dict, td=None) -> Dict: :return: state: Dict """ - # e0 = jnp.zeros((cfg["grid"]["nx"], cfg["grid"]["ny"], 2), dtype=jnp.complex128) - # phi = jnp.zeros((cfg["grid"]["nx"], cfg["grid"]["ny"]), dtype=jnp.complex128) - # phi += ( - # 1e-3 - # * jnp.exp(-(((cfg["grid"]["x"][:, None] - 2000) / 400.0) ** 2.0)) - # * jnp.exp(-1j * 0.2 * cfg["grid"]["x"][:, None]) - # ) - e0 = jnp.concatenate( - [jnp.exp(1j * cfg["drivers"]["E0"]["k0"] * cfg["grid"]["x"])[:, None] for _ in range(cfg["grid"]["ny"])], - axis=-1, - ) - e0 = jnp.concatenate([e0[:, :, None], jnp.zeros_like(e0)[:, :, None]], axis=-1) - e0 *= cfg["drivers"]["E0"]["a0"] - if cfg["density"]["noise"]["type"] == "uniform": random_amps = np.random.uniform( cfg["density"]["noise"]["min"], cfg["density"]["noise"]["max"], (cfg["grid"]["nx"], cfg["grid"]["ny"]) @@ -220,28 +324,98 @@ def init_state(cfg: Dict, td=None) -> Dict: raise NotImplementedError random_phases = np.random.uniform(0, 2 * np.pi, (cfg["grid"]["nx"], cfg["grid"]["ny"])) + phi_noise = 1 * jnp.exp(1j * random_phases) + epw = 0 * phi_noise - phi = random_amps * np.exp(1j * random_phases) - phi = jnp.fft.fft2(phi) + background_density = get_density_profile(cfg) + vte_sq = np.ones((cfg["grid"]["nx"], cfg["grid"]["ny"])) * cfg["units"]["derived"]["vte"] ** 2 + E0 = np.zeros((cfg["grid"]["nx"], cfg["grid"]["ny"], 2), dtype=np.complex128) + state = {"background_density": background_density, "epw": epw, "E0": E0, "vte_sq": vte_sq} + drivers = assemble_bandwidth(cfg) + return {k: v.view(dtype=np.float64) for k, v in state.items()}, {"drivers": drivers} + + +def assemble_bandwidth(cfg: Dict) -> Dict: + drivers = {"E0": {}} + num_colors = cfg["drivers"]["E0"]["num_colors"] + + if num_colors == 1: + drivers["E0"]["delta_omega"] = np.zeros(1) + drivers["E0"]["initial_phase"] = np.zeros(1) + drivers["E0"]["amplitudes"] = np.ones(1) + else: + delta_omega_max = cfg["drivers"]["E0"]["delta_omega_max"] + delta_omega = np.linspace(-delta_omega_max, delta_omega_max, num_colors) + + drivers["E0"]["delta_omega"] = delta_omega + drivers["E0"]["initial_phase"] = np.random.uniform(0, 2 * np.pi, num_colors) + + if cfg["drivers"]["E0"]["amplitude_shape"] == "uniform": + drivers["E0"]["amplitudes"] = np.ones(num_colors) + elif cfg["drivers"]["E0"]["amplitude_shape"] == "gaussian": + drivers["E0"]["amplitudes"] = ( + 2 + * np.log(2) + / delta_omega_max + / np.sqrt(np.pi) + * np.exp(-4 * np.log(2) * (delta_omega / delta_omega_max) ** 2.0) + ) + drivers["E0"]["amplitudes"] = np.sqrt(drivers["E0"]["amplitudes"]) # for amplitude from intensity + + elif cfg["drivers"]["E0"]["amplitude_shape"] == "lorentzian": + drivers["E0"]["amplitudes"] = ( + 1 / np.pi * (delta_omega_max / 2) / (delta_omega**2.0 + (delta_omega_max / 2) ** 2.0) + ) + drivers["E0"]["amplitudes"] = np.sqrt(drivers["E0"]["amplitudes"]) # for amplitude from intensity + elif cfg["drivers"]["E0"]["amplitude_shape"] == "ML" or cfg["drivers"]["E0"]["amplitude_shape"] == "opt": + drivers["E0"]["amplitudes"] = np.ones(num_colors) # will be modified elsewhere + elif cfg["drivers"]["E0"]["amplitude_shape"] == "file": + import tempfile + + with tempfile.TemporaryDirectory() as td: + + import pickle + + if cfg["drivers"]["E0"]["file"].startswith("s3"): + import boto3 + + fname = cfg["drivers"]["E0"]["file"] + + bucket = fname.split("/")[2] + key = "/".join(fname.split("/")[3:]) + s3 = boto3.client("s3") + s3.download_file(bucket, key, local_fname := os.path.join(td, "drivers.pkl")) + else: + local_fname = cfg["drivers"]["E0"]["file"] + + with open(local_fname, "rb") as fi: + drivers = pickle.load(fi) + else: + raise NotImplemented + + drivers["E0"]["amplitudes"] /= np.sum(drivers["E0"]["amplitudes"]) + + return drivers + + +def get_density_profile(cfg: Dict): if cfg["density"]["basis"] == "uniform": nprof = np.ones((cfg["grid"]["nx"], cfg["grid"]["ny"])) elif cfg["density"]["basis"] == "linear": - left = cfg["density"]["center"] - cfg["density"]["width"] * 0.5 - right = cfg["density"]["center"] + cfg["density"]["width"] * 0.5 - rise = cfg["density"]["rise"] - mask = get_envelope(rise, rise, left, right, cfg["grid"]["x"]) - - ureg = pint.UnitRegistry() - _Q = ureg.Quantity - - L = ( - _Q(cfg["density"]["gradient scale length"]).to("nm").magnitude - / cfg["units"]["derived"]["x0"].to("nm").magnitude + left = cfg["grid"]["xmin"] + _Q("5.0um").to("um").value + right = cfg["grid"]["xmax"] - _Q("5.0um").to("um").value + rise = _Q("0.5um").to("um").value + # mask = np.repeat(get_envelope(rise, rise, left, right, cfg["grid"]["x"])[:, None], cfg["grid"]["ny"], axis=-1) + # midpt = (cfg["grid"]["xmax"] + cfg["grid"]["xmin"]) / 2 + + nprof = ( + cfg["density"]["min"] + + (cfg["density"]["max"] - cfg["density"]["min"]) * cfg["grid"]["x"] / cfg["grid"]["xmax"] ) - nprof = cfg["density"]["val at center"] + (cfg["grid"]["x"] - cfg["density"]["center"]) / L - nprof = mask * nprof + # nprof = mask * nprof[:, None] + nprof = np.repeat(nprof[:, None], cfg["grid"]["ny"], axis=-1) elif cfg["density"]["basis"] == "exponential": left = cfg["density"]["center"] - cfg["density"]["width"] * 0.5 @@ -249,13 +423,7 @@ def init_state(cfg: Dict, td=None) -> Dict: rise = cfg["density"]["rise"] mask = get_envelope(rise, rise, left, right, cfg["grid"]["x"]) - ureg = pint.UnitRegistry() - _Q = ureg.Quantity - - L = ( - _Q(cfg["density"]["gradient scale length"]).to("nm").magnitude - / cfg["units"]["derived"]["x0"].to("nm").magnitude - ) + L = _Q(cfg["density"]["gradient scale length"]).to("nm").value / cfg["units"]["derived"]["x0"].to("nm").value nprof = cfg["density"]["val at center"] * np.exp((cfg["grid"]["x"] - cfg["density"]["center"]) / L) nprof = mask * nprof @@ -277,120 +445,26 @@ def init_state(cfg: Dict, td=None) -> Dict: else: raise NotImplementedError - state = { - "e0": e0, - "nb": nprof, - "temperature": jnp.ones_like(e0[..., 0], dtype=jnp.float64), - "dn": jnp.zeros_like(e0[..., 0], dtype=jnp.float64), - "phi": phi, - "delta": jnp.zeros_like(e0[..., 0], dtype=jnp.float64), - } - - if td is not None: - plot_dir = os.path.join(td, "plots", "init_state") - os.makedirs(plot_dir) - - for comp, label in zip(np.arange(2), ["x", "y"]): - for func, nm in zip([np.real, np.abs], ["real", "abs"]): - fig, ax = plt.subplots(1, 1, figsize=(10, 4), tight_layout=True) - cb = ax.contourf(cfg["grid"]["x"], cfg["grid"]["y"], func(state["e0"][..., comp].T), 32) - ax.grid() - ax.set_xlabel("x") - ax.set_ylabel("y") - ax.set_title(f"{nm}(e0_{label}(x,y))") - fig.colorbar(cb) - fig.savefig(os.path.join(plot_dir, f"{nm}-e0-{label}.png"), bbox_inches="tight") - plt.close() - - for k in ["nb", "dn", "temperature", "delta"]: - fig, ax = plt.subplots(1, 1, figsize=(10, 4), tight_layout=True) - cb = ax.contourf(cfg["grid"]["x"], cfg["grid"]["y"], state[k].T, 32) - ax.grid() - ax.set_xlabel("x") - ax.set_ylabel("y") - ax.set_title(k) - fig.colorbar(cb) - fig.savefig(os.path.join(plot_dir, f"{k}.png"), bbox_inches="tight") - plt.close() - - for func, nm in zip([np.real, np.abs], ["real", "abs"]): - fig, ax = plt.subplots(1, 1, figsize=(10, 4), tight_layout=True) - cb = ax.contourf(cfg["grid"]["x"], cfg["grid"]["y"], func(state["phi"].T), 32) - ax.grid() - ax.set_xlabel("x") - ax.set_ylabel("y") - ax.set_title(f"{nm}(phi(x,y))") - fig.colorbar(cb) - fig.savefig(os.path.join(plot_dir, f"{nm}-phi.png"), bbox_inches="tight") - plt.close() - - return {k: v.view(dtype=np.float64) for k, v in state.items()} - - -def get_more_units(cfg: Dict): - """ - - :type cfg: object - """ - - # ureg = pint.UnitRegistry() - # _Q = ureg.Quantity - import astropy.units as u - - n0 = _Q(cfg["units"]["normalizing density"]).to("1/cc") - wp0 = np.sqrt(n0 * ureg.e**2.0 / (ureg.m_e * ureg.epsilon_0)).to("rad/s") - T0 = _Q(cfg["units"]["normalizing temperature"]).to("eV") - v0 = np.sqrt(2.0 * T0 / ureg.m_e).to("m/s") - c_light = _Q(1.0 * ureg.c).to("m/s") / v0 - - _nuei_ = 0.0 - # fundamental_electron_collision_freq( - # T_e=(Te := _Q(cfg["units"]["electron temperature"]).to("eV")).magnitude * u.eV, - # n_e=n0.to("1/m^3").magnitude / u.m**3, - # ion=f'{cfg["units"]["gas fill"]} {cfg["units"]["ionization state"]}+', - # ).value - # cfg["units"]["derived"]["nuei"] = _Q(f"{_nuei_} Hz") - # cfg["units"]["derived"]["nuei_norm"] = (cfg["units"]["derived"]["nuei"].to("rad/s") / wp0).magnitude - - lambda_0 = _Q(cfg["units"]["laser wavelength"]) - laser_frequency = (2 * np.pi / lambda_0 * ureg.c).to("rad/s") - laser_period = (1 / laser_frequency).to("fs") - - e_laser = np.sqrt(2.0 * _Q(cfg["drivers"]["E0"]["intensity"]) / ureg.c / ureg.epsilon_0).to("V/m") - e_norm = (ureg.m_e * (np.sqrt(2.0 * Te / ureg.m_e).to("m/s")) * laser_frequency / ureg.e).to("V/m") - - cfg["units"]["derived"]["electric field"] = e_norm - cfg["units"]["derived"]["laser field"] = e_laser - - cfg["drivers"]["E0"]["w0"] = (laser_frequency / wp0).magnitude - cfg["drivers"]["E0"]["a0"] = (e_laser / e_norm).magnitude - cfg["drivers"]["E0"]["k0"] = np.sqrt( - (cfg["drivers"]["E0"]["w0"] ** 2.0 - cfg["plasma"]["wp0"] ** 2.0) / c_light.magnitude**2.0 - ) - - print("laser parameters: ") - print(f'w0 = {round(cfg["drivers"]["E0"]["w0"], 4)}') - print(f'k0 = {round(cfg["drivers"]["E0"]["k0"], 4)}') - print(f'a0 = {round(cfg["drivers"]["E0"]["a0"], 4)}') - print() - - return cfg + return nprof def plot_fields(fields, td): - t_skip = int(fields.coords["t"].data.size // 8) + t_skip = int(fields.coords["t (ps)"].data.size // 8) t_skip = t_skip if t_skip > 1 else 1 tslice = slice(0, -1, t_skip) + dx = fields.coords["x (um)"].data[1] - fields.coords["x (um)"].data[0] + dy = fields.coords["y (um)"].data[1] - fields.coords["y (um)"].data[0] + for k, v in fields.items(): fld_dir = os.path.join(td, "plots", k) os.makedirs(fld_dir) - np.abs(v[tslice]).T.plot(col="t", col_wrap=4) + np.abs(v[tslice]).T.plot(col="t (ps)", col_wrap=4) plt.savefig(os.path.join(fld_dir, f"{k}_x.png"), bbox_inches="tight") plt.close() - np.real(v[tslice]).T.plot(col="t", col_wrap=4) + np.real(v[tslice]).T.plot(col="t (ps)", col_wrap=4) plt.savefig(os.path.join(fld_dir, f"{k}_x_r.png"), bbox_inches="tight") plt.close() @@ -398,18 +472,18 @@ def plot_fields(fields, td): # np.abs(v[:, 1, 0]).plot(ax=ax) # fig.savefig(os.path.join(td, "plots", f"{k}_k1.png")) # plt.close() - ymidpt = int(fields.coords["y"].data.size // 2) + ymidpt = int(fields.coords["y (um)"].data.size // 2) slice_dir = os.path.join(fld_dir, "slice-along-x") os.makedirs(slice_dir) - np.log10(np.abs(v[tslice, :, ymidpt])).plot(col="t", col_wrap=4) + np.log10(np.abs(v[tslice, :, ymidpt])).plot(col="t (ps)", col_wrap=4) plt.savefig(os.path.join(slice_dir, f"log-{k}.png")) plt.close() - np.abs(v[tslice, :, ymidpt]).plot(col="t", col_wrap=4) + np.abs(v[tslice, :, ymidpt]).plot(col="t (ps)", col_wrap=4) plt.savefig(os.path.join(slice_dir, f"{k}.png")) plt.close() - np.real(v[tslice, :, ymidpt]).plot(col="t", col_wrap=4) + np.real(v[tslice, :, ymidpt]).plot(col="t (ps)", col_wrap=4) plt.savefig(os.path.join(slice_dir, f"real-{k}.png")) plt.close() @@ -425,137 +499,191 @@ def plot_fields(fields, td): plt.savefig(os.path.join(slice_dir, f"spacetime-real-{k}.png")) plt.close() + # plot total electric field energy in box vs time + fig, ax = plt.subplots(1, 2, figsize=(10, 4), tight_layout=True) + total_e_sq = np.abs(fields["ex"].data ** 2 + fields["ey"].data ** 2).sum(axis=(1, 2)) * dx * dy + ax[0].plot(fields.coords["t (ps)"].data, total_e_sq) + ax[0].set_xlabel("t (ps)") + ax[0].set_ylabel("Total E^2") + + ax[1].semilogy(fields.coords["t (ps)"].data, total_e_sq) + ax[1].set_xlabel("t (ps)") + ax[1].set_ylabel("Total E^2") + + ax[0].grid() + ax[1].grid() + + fig.savefig(os.path.join(td, "plots", "total_e_sq.png")) + plt.close() + def plot_kt(kfields, td): - t_skip = int(kfields.coords["t"].data.size // 8) + t_skip = int(kfields.coords["t (ps)"].data.size // 8) t_skip = t_skip if t_skip > 1 else 1 tslice = slice(0, -1, t_skip) + k_min = -2.5 + k_max = 2.5 + + ikx_min = np.argmin(np.abs(kfields.coords["kx"].data - k_min)) + ikx_max = np.argmin(np.abs(kfields.coords["kx"].data - k_max)) + iky_min = np.argmin(np.abs(kfields.coords["ky"].data - k_min)) + iky_max = np.argmin(np.abs(kfields.coords["ky"].data - k_max)) + + kx_slice = slice(ikx_min, ikx_max) + ky_slice = slice(iky_min, iky_max) + for k, v in kfields.items(): fld_dir = os.path.join(td, "plots", k) os.makedirs(fld_dir, exist_ok=True) - np.log10(np.abs(v[tslice, :, 0])).T.plot(col="t", col_wrap=4) - plt.savefig(os.path.join(fld_dir, f"{k}_kx.png"), bbox_inches="tight") + np.log10(np.abs(v[tslice, kx_slice, 0])).T.plot(col="t (ps)", col_wrap=4) + plt.savefig(os.path.join(fld_dir, f"log_{k}_kx.png"), bbox_inches="tight") plt.close() - np.abs(v[tslice, :, :]).T.plot(col="t", col_wrap=4) + np.abs(v[tslice, kx_slice, ky_slice]).T.plot(col="t (ps)", col_wrap=4) plt.savefig(os.path.join(fld_dir, f"{k}_kx_ky.png"), bbox_inches="tight") plt.close() - # np.log10(np.abs(v[tslice, :, :])).T.plot(col="t", col_wrap=4) - # plt.savefig(os.path.join(fld_dir, f"{k}_kx_ky.png"), bbox_inches="tight") - # plt.close() + np.log10(np.abs(v[tslice, kx_slice, ky_slice])).T.plot(col="t (ps)", col_wrap=4) + plt.savefig(os.path.join(fld_dir, f"log_{k}_kx_ky.png"), bbox_inches="tight") + plt.close() # # kx = kfields.coords["kx"].data -def post_process(result, cfg: Dict, td: str) -> Tuple[xr.Dataset, xr.Dataset]: +def post_process(sim_out, cfg: Dict, td: str, args) -> Tuple[xr.Dataset, xr.Dataset]: + + if isinstance(sim_out, tuple): + val, actual_sim_out = sim_out[0] + grad = sim_out[1] + result = actual_sim_out["solver_result"] + used_driver = actual_sim_out["args"]["drivers"] + else: + result = sim_out["solver_result"] + used_driver = sim_out["args"]["drivers"] + import pickle + + with open(os.path.join(td, "used_driver.pkl"), "wb") as fi: + pickle.dump(used_driver, fi) + + dw_over_w = used_driver["E0"]["delta_omega"] # / cfg["units"]["derived"]["w0"] - 1 + fig, ax = plt.subplots(1, 3, figsize=(13, 5), tight_layout=True) + ax[0].plot(dw_over_w, used_driver["E0"]["amplitudes"], "o") + ax[0].grid() + ax[0].set_xlabel(r"$\Delta \omega / \omega_0$", fontsize=14) + ax[0].set_ylabel("$|E|$", fontsize=14) + ax[1].semilogy(dw_over_w, used_driver["E0"]["amplitudes"], "o") + ax[1].grid() + ax[1].set_xlabel(r"$\Delta \omega / \omega_0$", fontsize=14) + ax[1].set_ylabel("$|E|$", fontsize=14) + ax[2].plot(dw_over_w, used_driver["E0"]["initial_phase"], "o") + ax[2].grid() + ax[2].set_xlabel(r"$\Delta \omega / \omega_0$", fontsize=14) + ax[2].set_ylabel(r"$\angle E$", fontsize=14) + plt.savefig(os.path.join(td, "learned_bandwidth.png"), bbox_inches="tight") + plt.close() + os.makedirs(os.path.join(td, "binary")) kfields, fields = make_xarrays(cfg, result.ts, result.ys, td) plot_fields(fields, td) - # plot_kt(kfields, td) - - return kfields, fields + plot_kt(kfields, td) + dx = fields.coords["x (um)"].data[1] - fields.coords["x (um)"].data[0] + dy = fields.coords["y (um)"].data[1] - fields.coords["y (um)"].data[0] + dt = fields.coords["t (ps)"].data[1] - fields.coords["t (ps)"].data[0] -def make_xarrays(cfg, this_t, state, td): - phi_vs_t = state["phi"].view(np.complex128) - phi_k = xr.DataArray(phi_vs_t, coords=(("t", this_t), ("kx", cfg["grid"]["kx"]), ("ky", cfg["grid"]["ky"]))) - - ex_k = xr.DataArray( - -1j * cfg["grid"]["kx"][:, None] * phi_vs_t, - coords=(("t", this_t), ("kx", cfg["grid"]["kx"]), ("ky", cfg["grid"]["ky"])), + metrics = {} + metrics["total_e_sq"] = float( + np.sum(np.abs(fields["ex"][-20:].data) ** 2 + np.abs(fields["ey"][-20:].data ** 2) * dx * dy * dt) ) + metrics["log10_total_e_sq"] = float(np.log10(metrics["total_e_sq"])) - ey_k = xr.DataArray( - -1j * cfg["grid"]["ky"][None, :] * phi_vs_t, - coords=(("t", this_t), ("kx", cfg["grid"]["kx"]), ("ky", cfg["grid"]["ky"])), - ) + if isinstance(sim_out, tuple): + if "loss_dict" in sim_out[0][1]: + for k, v in sim_out[0][1]["loss_dict"].items(): + metrics[k] = float(v) - phi_x = xr.DataArray( - np.fft.ifft2(phi_vs_t) / cfg["grid"]["nx"] / cfg["grid"]["ny"] * 4, - coords=(("t", this_t), ("x", cfg["grid"]["x"]), ("y", cfg["grid"]["y"])), - ) + mlflow.log_metrics(metrics) - ex = xr.DataArray( - -np.fft.ifft2(1j * cfg["grid"]["kx"][:, None] * phi_vs_t) / cfg["grid"]["nx"] / cfg["grid"]["ny"] * 4, - coords=(("t", this_t), ("x", cfg["grid"]["x"]), ("y", cfg["grid"]["y"])), - ) - ey = xr.DataArray( - -np.fft.ifft2(1j * cfg["grid"]["ky"][None, :] * phi_vs_t) / cfg["grid"]["nx"] / cfg["grid"]["ny"] * 4, - coords=(("t", this_t), ("x", cfg["grid"]["x"]), ("y", cfg["grid"]["y"])), - ) + return kfields, fields - e0x = xr.DataArray( - state["e0"].view(np.complex128)[..., 0], - coords=(("t", this_t), ("x", cfg["grid"]["x"]), ("y", cfg["grid"]["y"])), - ) - e0y = xr.DataArray( - state["e0"].view(np.complex128)[..., 1], - coords=(("t", this_t), ("x", cfg["grid"]["x"]), ("y", cfg["grid"]["y"])), - ) +def make_xarrays(cfg, this_t, state, td): + if "x" in cfg["save"]: + kx = cfg["save"]["kx"] + ky = cfg["save"]["ky"] + xax = cfg["save"]["x"]["ax"] + yax = cfg["save"]["y"]["ax"] + nx = cfg["save"]["x"]["ax"].size + ny = cfg["save"]["y"]["ax"].size - delta = xr.DataArray(state["delta"], coords=(("t", this_t), ("x", cfg["grid"]["x"]), ("y", cfg["grid"]["y"]))) + else: + kx = cfg["grid"]["kx"] + ky = cfg["grid"]["ky"] + xax = cfg["grid"]["x"] + yax = cfg["grid"]["y"] + nx = cfg["grid"]["nx"] + ny = cfg["grid"]["ny"] + + shift_kx = np.fft.fftshift(kx) * cfg["units"]["derived"]["c"] / cfg["units"]["derived"]["w0"] + shift_ky = np.fft.fftshift(ky) * cfg["units"]["derived"]["c"] / cfg["units"]["derived"]["w0"] + + tax_tuple = ("t (ps)", this_t) + xax_tuple = ("x (um)", xax) + yax_tuple = ("y (um)", yax) + + phi_vs_t = state["epw"].view(np.complex128) + phi_k_np = np.fft.fft2(phi_vs_t, axes=(1, 2)) + ex_k_np = -1j * kx[None, :, None] * phi_k_np + ey_k_np = -1j * ky[None, None, :] * phi_k_np + + phi_k = xr.DataArray(np.fft.fftshift(phi_k_np, axes=(1, 2)), coords=(tax_tuple, ("kx", shift_kx), ("ky", shift_ky))) + ex_k = xr.DataArray(np.fft.fftshift(ex_k_np, axes=(1, 2)), coords=(tax_tuple, ("kx", shift_kx), ("ky", shift_ky))) + ey_k = xr.DataArray(np.fft.fftshift(ey_k_np, axes=(1, 2)), coords=(tax_tuple, ("kx", shift_kx), ("ky", shift_ky))) + phi_x = xr.DataArray(phi_vs_t, coords=(tax_tuple, xax_tuple, yax_tuple)) + ex = xr.DataArray(np.fft.ifft2(ex_k_np, axes=(1, 2)) / nx / ny * 4, coords=(tax_tuple, xax_tuple, yax_tuple)) + ey = xr.DataArray(np.fft.ifft2(ey_k_np, axes=(1, 2)) / nx / ny * 4, coords=(tax_tuple, xax_tuple, yax_tuple)) + e0x = xr.DataArray(state["E0"].view(np.complex128)[..., 0], coords=(tax_tuple, xax_tuple, yax_tuple)) + e0y = xr.DataArray(state["E0"].view(np.complex128)[..., 1], coords=(tax_tuple, xax_tuple, yax_tuple)) + + background_density = xr.DataArray(state["background_density"], coords=(tax_tuple, xax_tuple, yax_tuple)) + + # delta = xr.DataArray(state["delta"], coords=(tax_tuple, xax_tuple, yax_tuple)) kfields = xr.Dataset({"phi": phi_k, "ex": ex_k, "ey": ey_k}) - fields = xr.Dataset({"phi": phi_x, "ex": ex, "ey": ey, "delta": delta, "e0_x": e0x, "e0_y": e0y}) - # kfields.to_netcdf(os.path.join(td, "binary", "k-fields.xr"), engine="h5netcdf", invalid_netcdf=True) + fields = xr.Dataset( + {"phi": phi_x, "ex": ex, "ey": ey, "e0_x": e0x, "e0_y": e0y, "background_density": background_density} + ) + kfields.to_netcdf(os.path.join(td, "binary", "k-fields.xr"), engine="h5netcdf", invalid_netcdf=True) fields.to_netcdf(os.path.join(td, "binary", "fields.xr"), engine="h5netcdf", invalid_netcdf=True) return kfields, fields -def get_models(model_config: Dict) -> defaultdict[eqx.Module]: - if model_config: - model_keys = jax.random.split(jax.random.PRNGKey(420), len(model_config.keys())) - model_dict = defaultdict(eqx.Module) - for (term, config), this_key in zip(model_config.items(), model_keys): - if term == "file": - pass +def get_models(all_models_config: Dict) -> defaultdict[eqx.Module]: + models = {} + for nm, this_models_config in all_models_config.items(): + if "file" in this_models_config: + file_path = this_models_config["file"] + if file_path.endswith(".pkl"): + import pickle + + with open(file_path, "rb") as fi: + models[nm] = pickle.load(fi) + print(models) + print(f"Loading {nm} weights from file {file_path} and ignoring any other specifications.") + elif file_path.endswith(".eqx"): + models[nm], _ = nn.load(file_path) + + print(f"Loading {nm} model from file {file_path} and ignoring any other specifications.") + else: + if this_models_config["type"] == "MLP": + models[nm] = nn.DriverModel(**this_models_config["config"]) + elif this_models_config["type"] == "VAE": + models[nm] = nn.VAE(**this_models_config["config"]) else: - for act in ["activation", "final_activation"]: - if config[act] == "tanh": - config[act] = jnp.tanh - - model_dict[term] = eqx.nn.MLP(**{**config, "key": this_key}) - if model_config["file"]: - model_dict = eqx.tree_deserialise_leaves(model_config["file"], model_dict) - - return model_dict - else: - return False - + raise NotImplementedError -def mva(actual_ek1, mod_defaults, results, td, coords): - loss_t = np.linspace(200, 400, 64) - ek1 = -1j * mod_defaults["grid"]["kx"][None, :, None] * results.ys["phi"].view(np.complex128) - ek1 = jnp.mean(jnp.abs(ek1[:, -1, :]), axis=-1) - rescaled_ek1 = ek1 / jnp.amax(ek1) * np.amax(actual_ek1.data) - # interp_ek1 = jnp.interp(loss_t, mod_defaults["save"]["t"]["ax"], rescaled_ek1) - - fig, ax = plt.subplots(1, 2, figsize=(10, 4), tight_layout=True) - ax[0].plot(coords["t"].data, actual_ek1, label="Vlasov") - ax[0].plot(mod_defaults["save"]["t"]["ax"], rescaled_ek1, label="NN + Fluid") - ax[0].axvspan(loss_t[0], loss_t[-1], alpha=0.1) - ax[1].semilogy(coords["t"].data, actual_ek1, label="Vlasov") - ax[1].semilogy(mod_defaults["save"]["t"]["ax"], rescaled_ek1, label="NN + Fluid") - ax[1].axvspan(loss_t[0], loss_t[-1], alpha=0.1) - ax[0].set_xlabel(r"t ($\omega_p^{-1}$)", fontsize=12) - ax[1].set_xlabel(r"t ($\omega_p^{-1}$)", fontsize=12) - ax[0].set_ylabel(r"$|\hat{n}|^{1}$", fontsize=12) - ax[0].grid() - ax[1].grid() - ax[0].legend(fontsize=14) - fig.savefig(os.path.join(td, "plots", "vlasov_v_fluid.png"), bbox_inches="tight") - plt.close(fig) - - -def get_diffeqsolve_quants(cfg): - return dict( - terms=ODETerm(integrator.VectorField(cfg)), - solver=integrator.Stepper(), - saveat=dict(ts=cfg["save"]["t"]["ax"]), # , fn=cfg["save"]["func"]["callable"]), - ) + return models diff --git a/adept/lpse2d/modes/bandwidth.py b/adept/lpse2d/modes/bandwidth.py new file mode 100644 index 0000000..943f012 --- /dev/null +++ b/adept/lpse2d/modes/bandwidth.py @@ -0,0 +1,177 @@ +from typing import Dict + +from jax import numpy as jnp +from jax.random import normal, PRNGKey +import numpy as np +from diffrax import diffeqsolve, SaveAt +from equinox import filter_value_and_grad, filter_jit + +from adept.lpse2d.run_helpers import get_diffeqsolve_quants + + +def get_apply_func(cfg): + """ + This function applies models or weights to the state and args or just returns the config values + that have already been initialized if neither are present + + In the case of a parameter learning problem, or the case where learned parameters + are loaded, it goes into the optimization condition, where the learned parameters are + applied to the state and args + + Otherwise, this function will use an NN to generate the modification to the state and args. + The NN is typically a function of some other variables in state and args + + + """ + + def _unnorm_weights_(amps_and_phases: Dict, these_args: Dict): + amps = amps_and_phases["amps"] + phases = amps_and_phases["phases"] + + these_args["drivers"]["E0"]["amplitudes"] = jnp.tanh(amps) + these_args["drivers"]["E0"]["initial_phase"] = jnp.tanh(phases) + + these_args["drivers"]["E0"]["delta_omega"] = jnp.linspace( + -cfg["drivers"]["E0"]["delta_omega_max"], + cfg["drivers"]["E0"]["delta_omega_max"], + num=cfg["drivers"]["E0"]["num_colors"], + ) + + these_args["drivers"]["E0"]["amplitudes"] *= 2.0 # from [-1, 1] to [-2, 2] + these_args["drivers"]["E0"]["amplitudes"] -= 2.0 # from [-2, 2] to [-4, 0] + these_args["drivers"]["E0"]["amplitudes"] = jnp.power( + 10.0, these_args["drivers"]["E0"]["amplitudes"] + ) # from [-4, 0] to [1e-4, 1] + these_args["drivers"]["E0"]["amplitudes"] /= jnp.sum(these_args["drivers"]["E0"]["amplitudes"]) + these_args["drivers"]["E0"]["initial_phase"] *= jnp.pi # from [-1, 1] to [-pi, pi] + + return these_args + + if "train" in cfg["mode"]: + + def apply_fn(models, _state_, _args_): + this_model = models["bandwidth"] + L = float(cfg["density"]["gradient scale length"].strip("um")) + I0 = float(cfg["units"]["laser intensity"].strip("W/cm^2")) + Te = float(cfg["units"]["reference electron temperature"].strip("eV")) + + Te = (Te - 3000) / 2000 + L = (L - 300) / 500 + I0 = (jnp.log10(I0) - 15) / 2 + + model_outputs = this_model(jnp.array([Te, L, I0])) + _args_ = _unnorm_weights_(model_outputs, _args_) + + return model_outputs, _state_, _args_ + + elif "optimize" in cfg["mode"]: + + def apply_fn(models, _state_, _args_): + if "hyperparams" in cfg["models"]["bandwidth"]: + these_params = models["bandwidth"]( + normal( + PRNGKey(seed=np.random.randint(2**20)), + shape=(cfg["models"]["bandwidth"]["hyperparams"]["input_width"],), + ) + ) + else: + these_params = models["bandwidth"] + _args_ = _unnorm_weights_(these_params, _args_) + return these_params, _state_, _args_ + + else: + + def apply_fn(models, _state_, _args_): + print("using config settings for bandwidth") + return None, _state_, _args_ + + return apply_fn + + +def get_run_fn(cfg): + """ + This function returns a function that will run the simulation and calculate the gradient + if specified + + """ + if cfg["mode"] == "train-bandwidth": + diffeqsolve_quants = get_diffeqsolve_quants(cfg) + + kx = cfg["save"]["kx"] if "kx" in cfg["save"] else cfg["grid"]["kx"] + ky = cfg["save"]["ky"] if "ky" in cfg["save"] else cfg["grid"]["ky"] + kx *= cfg["units"]["derived"]["c"] / cfg["units"]["derived"]["w0"] + ky *= cfg["units"]["derived"]["c"] / cfg["units"]["derived"]["w0"] + dx = cfg["save"]["x"]["dx"] if "dx" in cfg["save"]["x"] else cfg["grid"]["dx"] + dy = cfg["save"]["y"]["dy"] if "dy" in cfg["save"]["y"] else cfg["grid"]["dy"] + dt = cfg["save"]["t"]["dt"] if "dt" in cfg["save"]["t"] else cfg["grid"]["dt"] + + apply_models = get_apply_func(cfg) + + def _run_(_models_, _state_, _args_, time_quantities: Dict): + + model_output, _state_, _args_ = apply_models(_models_, _state_, _args_) + solver_result = diffeqsolve( + terms=diffeqsolve_quants["terms"], + solver=diffeqsolve_quants["solver"], + t0=time_quantities["t0"], + t1=time_quantities["t1"], + max_steps=cfg["grid"]["max_steps"], + dt0=cfg["grid"]["dt"], + y0=_state_, + args=_args_, + saveat=SaveAt(**diffeqsolve_quants["saveat"]), + ) + + phi_k = jnp.fft.fft2(solver_result.ys["epw"].view(jnp.complex128), axes=(1, 2)) + ex_k = kx[None, :, None] * phi_k + ey_k = ky[None, None, :] * phi_k + e_sq = jnp.sum(jnp.abs(ex_k) ** 2.0 + jnp.abs(ey_k) ** 2.0) * dx * dy * dt + loss = jnp.log10(e_sq) + loss_dict = {"loss": loss} + if cfg["models"]["bandwidth"]["type"] == "VAE": + loss += jnp.sum(model_output["kl_loss"]) + loss_dict["kl_loss"] = jnp.sum(model_output["kl_loss"]) + + return loss, {"solver_result": solver_result, "state": _state_, "args": _args_, "loss_dict": loss_dict} + + return filter_jit(filter_value_and_grad(_run_, has_aux=True)) + + elif cfg["mode"] == "optimize-bandwidth": + diffeqsolve_quants = get_diffeqsolve_quants(cfg) + + kx = cfg["save"]["kx"] if "kx" in cfg["save"] else cfg["grid"]["kx"] + ky = cfg["save"]["ky"] if "ky" in cfg["save"] else cfg["grid"]["ky"] + kx *= cfg["units"]["derived"]["c"] / cfg["units"]["derived"]["w0"] + ky *= cfg["units"]["derived"]["c"] / cfg["units"]["derived"]["w0"] + dx = cfg["save"]["x"]["dx"] if "dx" in cfg["save"]["x"] else cfg["grid"]["dx"] + dy = cfg["save"]["y"]["dy"] if "dy" in cfg["save"]["y"] else cfg["grid"]["dy"] + dt = cfg["save"]["t"]["dt"] if "dt" in cfg["save"]["t"] else cfg["grid"]["dt"] + + apply_parameters = get_apply_func(cfg) + + def _run_(_models_, _state_, _args_, time_quantities: Dict): + + _, _state_, _args_ = apply_parameters(_models_, _state_, _args_) + solver_result = diffeqsolve( + terms=diffeqsolve_quants["terms"], + solver=diffeqsolve_quants["solver"], + t0=time_quantities["t0"], + t1=time_quantities["t1"], + max_steps=cfg["grid"]["max_steps"], + dt0=cfg["grid"]["dt"], + y0=_state_, + args=_args_, + saveat=SaveAt(**diffeqsolve_quants["saveat"]), + ) + + phi_k = jnp.fft.fft2(solver_result.ys["epw"][-30:].view(jnp.complex128), axes=(1, 2)) + ex_k = kx[None, :, None] * phi_k + ey_k = ky[None, None, :] * phi_k + e_sq = jnp.sum(jnp.abs(ex_k) ** 2.0 + jnp.abs(ey_k) ** 2.0) * dx * dy * dt + loss = jnp.log10(e_sq) + loss_dict = {"loss": loss} + return loss, {"solver_result": solver_result, "state": _state_, "args": _args_, "loss_dict": loss_dict} + + return filter_jit(filter_value_and_grad(_run_, has_aux=True)) + else: + raise NotImplementedError("has to have train or optimize in the mode field of the config file") diff --git a/adept/lpse2d/nn.py b/adept/lpse2d/nn.py new file mode 100644 index 0000000..5b5c9f1 --- /dev/null +++ b/adept/lpse2d/nn.py @@ -0,0 +1,113 @@ +import jax +import equinox as eqx +import jax.numpy as jnp +import json +import numpy as np + + +class GenerativeDriver(eqx.Module): + amp_decoder: eqx.Module + phase_decoder: eqx.Module + + def __init__(self, decoder_width, decoder_depth, input_width, output_width, key): + super().__init__() + da_k, dp_k = jax.random.split(jax.random.PRNGKey(key), 2) + self.amp_decoder = eqx.nn.MLP( + input_width, output_width, width_size=decoder_width, depth=decoder_depth, key=da_k, activation=jnp.tanh + ) + self.phase_decoder = eqx.nn.MLP( + input_width, output_width, width_size=decoder_width, depth=decoder_depth, key=dp_k, activation=jnp.tanh + ) + + def __call__(self, x): + amps = self.amp_decoder(x) + phases = self.phase_decoder(x) + return {"amps": amps, "phases": phases} + + +class DriverModel(eqx.Module): + encoder: eqx.Module + amp_decoder: eqx.Module + phase_decoder: eqx.Module + + def __init__( + self, encoder_width, encoder_depth, decoder_width, decoder_depth, input_width, output_width, latent_width, key + ): + super().__init__() + e_k, da_k, dp_k = jax.random.split(jax.random.PRNGKey(key), 3) + self.encoder = eqx.nn.MLP( + input_width, latent_width, width_size=encoder_width, depth=encoder_depth, key=e_k, activation=jnp.tanh + ) + self.amp_decoder = eqx.nn.MLP( + latent_width, output_width, width_size=decoder_width, depth=decoder_depth, key=da_k, activation=jnp.tanh + ) + self.phase_decoder = eqx.nn.MLP( + latent_width, output_width, width_size=decoder_width, depth=decoder_depth, key=dp_k, activation=jnp.tanh + ) + + def __call__(self, x): + encoded = self.encoder(x) + amps = self.amp_decoder(encoded) + phases = self.phase_decoder(encoded) + return {"amps": amps, "phases": phases} + + +class DriverVAE(eqx.Module): + gen_k: jax.random.PRNGKey + encoder: eqx.Module + mu: eqx.Module + sigma: eqx.Module + amp_decoder: eqx.Module + phase_decoder: eqx.Module + + def __init__(self, input_width, output_width, latent_width, key): + super().__init__() + e_k, mu_k, sigma_k, da_k, dp_k = jax.random.split(jax.random.PRNGKey(key), 5) + self.gen_k = jax.random.PRNGKey(np.random.randint(0, 2**20)) + self.encoder = eqx.nn.Linear(input_width, latent_width, key=e_k) + self.mu = eqx.nn.Linear(latent_width, latent_width, key=mu_k) + self.sigma = eqx.nn.Linear(latent_width, latent_width, key=sigma_k) + self.amp_decoder = eqx.nn.Linear(latent_width, output_width, key=da_k) + self.phase_decoder = eqx.nn.Linear(latent_width, output_width, key=dp_k) + + def __call__(self, x): + latent = jnp.tanh(self.encoder(x)) + encoded_mu = jnp.tanh(self.mu(latent)) + encoded_sigma = jnp.tanh(self.sigma(latent)) + encoded_var = encoded_sigma**2.0 + log_var = jnp.log(encoded_var) + encoded = encoded_mu + encoded_sigma * jax.random.normal(self.gen_k, encoded_mu.shape) + + amps = self.amp_decoder(encoded) + phases = self.phase_decoder(encoded) + kl_loss = -0.5 * jnp.sum(1 + log_var - jnp.square(encoded_mu) - encoded_var) + + return {"amps": amps, "phases": phases, "kl_loss": kl_loss} + + +def save(filename, model_cfg, model): + with open(filename, "wb") as f: + model_cfg_str = json.dumps(model_cfg) + f.write((model_cfg_str + "\n").encode()) + eqx.tree_serialise_leaves(f, model) + + +def load(filename): + with open(filename, "rb") as f: + model_cfg = json.loads(f.readline().decode()) + if "type" in model_cfg: + hyperparams = model_cfg["hyperparams"] + if model_cfg["type"] == "VAE": + model = DriverVAE(**hyperparams) + elif model_cfg["type"] == "MLP": + model = DriverModel(**hyperparams) + elif model_cfg["type"] == "GEN": + model = GenerativeDriver(**hyperparams) + else: + raise NotImplementedError(f"Model type {model_cfg['type']} not implemented") + else: + model = DriverVAE(**model_cfg) + print("Model type not specified, defaulting to VAE. dangerous (and often probably just doesn't load)") + hyperparams = model_cfg + + return eqx.tree_deserialise_leaves(f, model), hyperparams diff --git a/adept/lpse2d/run_fns.py b/adept/lpse2d/run_fns.py new file mode 100644 index 0000000..61b79af --- /dev/null +++ b/adept/lpse2d/run_fns.py @@ -0,0 +1,58 @@ +from typing import Dict +from diffrax import diffeqsolve, SaveAt +from equinox import filter_jit + + +from adept.lpse2d.modes import bandwidth +from adept.lpse2d.run_helpers import get_diffeqsolve_quants + + +def get_apply_func(cfg): + apply_fncs = {} + if "models" in cfg: + if "bandwidth" in cfg["models"]: + apply_fncs["bandwidth"] = bandwidth.get_apply_func(cfg) + else: + raise NotImplementedError("Only bandwidth mode is implemented") + + def apply_fn(models, _state_, _args_): + model_out = {} + for key, fn in apply_fncs.items(): + model_out[key], _state_, _args_ = fn(models, _state_, _args_) + return model_out, _state_, _args_ + + return apply_fn + + +def get_run_fn(cfg): + + if "mode" in cfg: + if "bandwidth" in cfg["mode"]: + _run_ = bandwidth.get_run_fn(cfg) + else: + raise NotImplementedError("Only bandwidth mode is implemented") + else: + # if no mode is specified, then we are just running the simulation + diffeqsolve_quants = get_diffeqsolve_quants(cfg) + apply_models = get_apply_func(cfg) + + @filter_jit + def _run_(_models_, _state_, _args_, time_quantities: Dict): + + _, _state_, _args_ = apply_models(_models_, _state_, _args_) + + solver_result = diffeqsolve( + terms=diffeqsolve_quants["terms"], + solver=diffeqsolve_quants["solver"], + t0=time_quantities["t0"], + t1=time_quantities["t1"], + max_steps=cfg["grid"]["max_steps"], + dt0=cfg["grid"]["dt"], + y0=_state_, + args=_args_, + saveat=SaveAt(**diffeqsolve_quants["saveat"]), + ) + + return {"solver_result": solver_result, "state": _state_, "args": _args_} + + return _run_ diff --git a/adept/lpse2d/run_helpers.py b/adept/lpse2d/run_helpers.py new file mode 100644 index 0000000..0768c95 --- /dev/null +++ b/adept/lpse2d/run_helpers.py @@ -0,0 +1,94 @@ +from typing import Dict +from functools import partial +from diffrax import ODETerm +import interpax +import numpy as np +import jax.numpy as jnp +from astropy.units import Quantity as _Q + +from adept.lpse2d.core.integrator import SplitStep +from adept.vlasov1d.integrator import Stepper + + +def get_save_quantities(cfg: Dict) -> Dict: + """ + This function updates the config with the quantities required for the diagnostics and saving routines + + :param cfg: + :return: + """ + + # cfg["save"]["func"] = {**cfg["save"]["func"], **{"callable": get_save_func(cfg)}} + tmin = _Q(cfg["save"]["t"]["tmin"]).to("s").value / cfg["units"]["derived"]["timeScale"] + tmax = _Q(cfg["save"]["t"]["tmax"]).to("s").value / cfg["units"]["derived"]["timeScale"] + dt = _Q(cfg["save"]["t"]["dt"]).to("s").value / cfg["units"]["derived"]["timeScale"] + nt = int((tmax - tmin) / dt) + 1 + + cfg["save"]["t"]["dt"] = dt + cfg["save"]["t"]["ax"] = jnp.linspace(tmin, tmax, nt) + + if "x" in cfg["save"]: + xmin = cfg["grid"]["xmin"] + xmax = cfg["grid"]["xmax"] + dx = _Q(cfg["save"]["x"]["dx"]).to("m").value / cfg["units"]["derived"]["spatialScale"] * 100 + nx = int((xmax - xmin) / dx) + cfg["save"]["x"]["dx"] = dx + cfg["save"]["x"]["ax"] = jnp.linspace(xmin + dx / 2.0, xmax - dx / 2.0, nx) + cfg["save"]["kx"] = np.fft.fftfreq(nx, d=dx / 2.0 / np.pi) + + if "y" in cfg["save"]: + ymin = cfg["grid"]["ymin"] + ymax = cfg["grid"]["ymax"] + dy = _Q(cfg["save"]["y"]["dy"]).to("m").value / cfg["units"]["derived"]["spatialScale"] * 100 + ny = int((ymax - ymin) / dy) + cfg["save"]["y"]["dy"] = dy + cfg["save"]["y"]["ax"] = jnp.linspace(ymin + dy / 2.0, ymax - dy / 2.0, ny) + cfg["save"]["ky"] = np.fft.fftfreq(ny, d=dy / 2.0 / np.pi) + else: + raise NotImplementedError("Must specify y in save") + + xq, yq = jnp.meshgrid(cfg["save"]["x"]["ax"], cfg["save"]["y"]["ax"], indexing="ij") + + interpolator = partial( + interpax.interp2d, + xq=jnp.reshape(xq, (nx * ny), order="F"), + yq=jnp.reshape(yq, (nx * ny), order="F"), + x=cfg["grid"]["x"], + y=cfg["grid"]["y"], + method="linear", + ) + + def save_func(t, y, args): + save_y = {} + for k, v in y.items(): + if k == "E0": + cmplx_fld = v.view(jnp.complex128) + save_y[k] = jnp.concatenate( + [ + jnp.reshape(interpolator(f=cmplx_fld[..., ivec]), (nx, ny), order="F")[..., None] + for ivec in range(2) + ], + axis=-1, + ).view(jnp.float64) + elif k == "epw": + cmplx_fld = v.view(jnp.complex128) + save_y[k] = jnp.reshape(interpolator(f=cmplx_fld), (nx, ny), order="F").view(jnp.float64) + else: + save_y[k] = jnp.reshape(interpolator(f=v), (nx, ny), order="F") + + return save_y + + else: + save_func = lambda t, y, args: y + + cfg["save"]["func"] = save_func + + return cfg + + +def get_diffeqsolve_quants(cfg): + + cfg = get_save_quantities(cfg) + return dict( + terms=ODETerm(SplitStep(cfg)), solver=Stepper(), saveat=dict(ts=cfg["save"]["t"]["ax"], fn=cfg["save"]["func"]) + ) diff --git a/adept/lpse2d/train_damping.py b/adept/lpse2d/train_damping.py index e988ccb..fb5cdf1 100644 --- a/adept/lpse2d/train_damping.py +++ b/adept/lpse2d/train_damping.py @@ -73,7 +73,7 @@ def remote_run(run_id, t_or_v): "weights.eqx", artifact_uri=mlflow_run.info.artifact_uri, destination_path=td ) models = helpers.get_models(mod_defaults["models"]) - vf = integrator.VectorField(mod_defaults) + vf = integrator.SpectralPotential(mod_defaults) loss_t = np.linspace(200, 400, 64) t_factor = np.exp(-2 * (1 - (loss_t / mod_defaults["grid"]["tmax"]))) diff --git a/adept/sh2d/utils/helpers.py b/adept/sh2d/utils/helpers.py index df3bb16..26c0fe3 100644 --- a/adept/sh2d/utils/helpers.py +++ b/adept/sh2d/utils/helpers.py @@ -111,7 +111,7 @@ def get_save_quantities(cfg: Dict) -> Dict: return cfg -def init_state(cfg: Dict) -> Dict: +def init_state(cfg: Dict) -> tuple[Dict, Dict]: """ This function initializes the state @@ -148,7 +148,7 @@ def init_state(cfg: Dict) -> Dict: state["de"] = jnp.zeros((nx, ny, 3)) state["db"] = jnp.zeros((nx, ny, 3)) - return state + return state, {"drivers": cfg["drivers"]} class FokkerPlanckVectorField(eqx.Module): diff --git a/adept/tf1d/helpers.py b/adept/tf1d/helpers.py index fb75e03..7196bb9 100644 --- a/adept/tf1d/helpers.py +++ b/adept/tf1d/helpers.py @@ -11,7 +11,8 @@ from jax import tree_util as jtu from flatdict import FlatDict import equinox as eqx -from diffrax import ODETerm, Tsit5 +from diffrax import ODETerm, Tsit5, diffeqsolve, SaveAt +from equinox import filter_jit from jax import numpy as jnp from adept.tf1d import pushers @@ -125,7 +126,9 @@ def plot_xrs(which, td, xrs): plt.close(fig) -def post_process(result, cfg: Dict, td: str) -> Dict: +def post_process(result, cfg: Dict, td: str, args: Dict = None) -> Dict: + result, state, args = result + os.makedirs(os.path.join(td, "binary")) os.makedirs(os.path.join(td, "plots")) @@ -220,6 +223,7 @@ def get_save_quantities(cfg: Dict) -> Dict: def get_diffeqsolve_quants(cfg): + cfg = get_save_quantities(cfg) return dict( terms=ODETerm(VectorField(cfg)), solver=Tsit5(), @@ -227,7 +231,33 @@ def get_diffeqsolve_quants(cfg): ) -def init_state(cfg: Dict, td) -> Dict: +def get_run_fn(cfg): + diffeqsolve_quants = get_diffeqsolve_quants(cfg) + + @filter_jit + def _run_(_models_, _state_, _args_, time_quantities: Dict): + + _state_, _args_ = apply_models(_models_, _state_, _args_, cfg) + # if "terms" in cfg.keys(): + # args["terms"] = cfg["terms"] + solver_result = diffeqsolve( + terms=diffeqsolve_quants["terms"], + solver=diffeqsolve_quants["solver"], + t0=time_quantities["t0"], + t1=time_quantities["t1"], + max_steps=cfg["grid"]["max_steps"], + dt0=cfg["grid"]["dt"], + y0=_state_, + args=_args_, + saveat=SaveAt(**diffeqsolve_quants["saveat"]), + ) + + return solver_result, _state_, _args_ + + return _run_ + + +def init_state(cfg: Dict, td=None) -> tuple[Dict, Dict]: """ This function initializes the state @@ -243,7 +273,7 @@ def init_state(cfg: Dict, td) -> Dict: delta=jnp.zeros(cfg["grid"]["nx"]), ) - return state + return state, {"drivers": cfg["drivers"]} class VectorField(eqx.Module): @@ -393,3 +423,7 @@ def get_models(model_config: Dict) -> defaultdict[eqx.Module]: return model_dict else: return False + + +def apply_models(models, state, args, cfg): + return state, args diff --git a/adept/vfp1d/helpers.py b/adept/vfp1d/helpers.py index dfb9ab8..5ec0c4e 100644 --- a/adept/vfp1d/helpers.py +++ b/adept/vfp1d/helpers.py @@ -11,8 +11,9 @@ import xarray, yaml, plasmapy from astropy import units as u, constants as csts from jax import numpy as jnp -from diffrax import ODETerm, SubSaveAt +from diffrax import ODETerm, SubSaveAt, diffeqsolve, SaveAt from matplotlib import pyplot as plt +from equinox import filter_jit from adept.vfp1d.storage import post_process, get_save_quantities @@ -363,7 +364,33 @@ def get_solver_quantities(cfg: Dict) -> Dict: return cfg_grid -def init_state(cfg: Dict, td=None) -> Dict: +def get_run_fn(cfg): + diffeqsolve_quants = get_diffeqsolve_quants(cfg) + + @filter_jit + def _run_(_models_, _state_, _args_, time_quantities: Dict): + + _state_, _args_ = apply_models(_models_, _state_, _args_, cfg) + # if "terms" in cfg.keys(): + # args["terms"] = cfg["terms"] + solver_result = diffeqsolve( + terms=diffeqsolve_quants["terms"], + solver=diffeqsolve_quants["solver"], + t0=time_quantities["t0"], + t1=time_quantities["t1"], + max_steps=cfg["grid"]["max_steps"], + dt0=cfg["grid"]["dt"], + y0=_state_, + args=_args_, + saveat=SaveAt(**diffeqsolve_quants["saveat"]), + ) + + return solver_result, _state_, _args_ + + return _run_ + + +def init_state(cfg: Dict, td=None) -> tuple[Dict, Dict]: """ This function initializes the state @@ -383,12 +410,17 @@ def init_state(cfg: Dict, td=None) -> Dict: state["Z"] = jnp.ones(cfg["grid"]["nx"]) state["ni"] = ne_prof / cfg["units"]["Z"] - return state + return state, {"drivers": cfg["drivers"]} def get_diffeqsolve_quants(cfg): + cfg = get_save_quantities(cfg) return dict( terms=ODETerm(OSHUN1D(cfg)), solver=Stepper(), saveat=dict(subs={k: SubSaveAt(ts=v["t"]["ax"], fn=v["func"]) for k, v in cfg["save"].items()}), ) + + +def apply_models(models, state, args, cfg): + return state, args diff --git a/adept/vfp1d/storage.py b/adept/vfp1d/storage.py index 06588b8..d847fae 100644 --- a/adept/vfp1d/storage.py +++ b/adept/vfp1d/storage.py @@ -181,7 +181,9 @@ def store_f(cfg: Dict, this_t: Dict, td: str, ys: Dict) -> xr.Dataset: return f_store -def post_process(result, cfg: Dict, td: str): +def post_process(result, cfg: Dict, td: str, args: Dict = None) -> Dict: + + result, state, args = result t0 = time() os.makedirs(os.path.join(td, "plots"), exist_ok=True) os.makedirs(os.path.join(td, "plots", "fields"), exist_ok=True) diff --git a/adept/vlasov1d/helpers.py b/adept/vlasov1d/helpers.py index 7bd2082..a4979d9 100644 --- a/adept/vlasov1d/helpers.py +++ b/adept/vlasov1d/helpers.py @@ -1,6 +1,6 @@ # Copyright (c) Ergodic LLC 2023 # research@ergodic.io -from typing import Dict +from typing import Dict, Tuple import os from time import time @@ -9,8 +9,9 @@ import numpy as np import xarray, mlflow, pint, yaml from jax import numpy as jnp -from diffrax import ODETerm, SubSaveAt +from diffrax import ODETerm, SubSaveAt, diffeqsolve, SaveAt from matplotlib import pyplot as plt +from equinox import filter_jit from adept.vlasov1d.integrator import VlasovMaxwell, Stepper from adept.vlasov1d.storage import store_f, store_fields, get_save_quantities @@ -343,7 +344,33 @@ def get_solver_quantities(cfg: Dict) -> Dict: return cfg_grid -def init_state(cfg: Dict, td) -> Dict: +def get_run_fn(cfg): + diffeqsolve_quants = get_diffeqsolve_quants(cfg) + + @filter_jit + def _run_(_models_, _state_, _args_, time_quantities: Dict): + + _state_, _args_ = apply_models(_models_, _state_, _args_, cfg) + if "terms" in cfg.keys(): + _args_["terms"] = cfg["terms"] + solver_result = diffeqsolve( + terms=diffeqsolve_quants["terms"], + solver=diffeqsolve_quants["solver"], + t0=time_quantities["t0"], + t1=time_quantities["t1"], + max_steps=cfg["grid"]["max_steps"], + dt0=cfg["grid"]["dt"], + y0=_state_, + args=_args_, + saveat=SaveAt(**diffeqsolve_quants["saveat"]), + ) + + return solver_result, _state_, _args_ + + return _run_ + + +def init_state(cfg: Dict, td) -> Tuple[Dict, Dict]: """ This function initializes the state @@ -362,10 +389,11 @@ def init_state(cfg: Dict, td) -> Dict: for field in ["a", "da", "prev_a"]: state[field] = jnp.zeros(cfg["grid"]["nx"] + 2) # need boundary cells - return state + return state, {"drivers": cfg["drivers"]} def get_diffeqsolve_quants(cfg): + cfg = get_save_quantities(cfg) return dict( terms=ODETerm(VlasovMaxwell(cfg)), solver=Stepper(), @@ -373,7 +401,9 @@ def get_diffeqsolve_quants(cfg): ) -def post_process(result, cfg: Dict, td: str): +def post_process(result, cfg: Dict, td: str, args: Dict): + result, _state_, _args_ = result + t0 = time() os.makedirs(os.path.join(td, "plots"), exist_ok=True) os.makedirs(os.path.join(td, "plots", "fields"), exist_ok=True) @@ -430,3 +460,7 @@ def post_process(result, cfg: Dict, td: str): mlflow.log_metrics({"postprocess_time_min": round((time() - t0) / 60, 3)}) return {"fields": fields_xr, "dists": f_xr, "scalars": scalars_xr} + + +def apply_models(models, state, args, cfg): + return state, args diff --git a/adept/vlasov1d/integrator.py b/adept/vlasov1d/integrator.py index f2ff4e3..184d13f 100644 --- a/adept/vlasov1d/integrator.py +++ b/adept/vlasov1d/integrator.py @@ -177,11 +177,14 @@ def __init__(self, cfg): self.cfg = cfg self.vpfp = VlasovPoissonFokkerPlanck(cfg) self.wave_solver = field.WaveSolver(c=1.0 / cfg["grid"]["beta"], dx=cfg["grid"]["dx"], dt=cfg["grid"]["dt"]) - self.compute_charges = partial(jnp.trapz, dx=cfg["grid"]["dv"], axis=1) + self.dt = self.cfg["grid"]["dt"] self.ey_driver = field.Driver(cfg["grid"]["x_a"], driver_key="ey") self.ex_driver = field.Driver(cfg["grid"]["x"], driver_key="ex") + def compute_charges(self, f): + return jnp.sum(f, axis=1) * self.cfg["grid"]["dv"] + def nu_prof(self, t, nu_args): t_L = nu_args["time"]["center"] - nu_args["time"]["width"] * 0.5 t_R = nu_args["time"]["center"] + nu_args["time"]["width"] * 0.5 diff --git a/adept/vlasov1d/pushers/field.py b/adept/vlasov1d/pushers/field.py index 9afbee8..8080e5e 100644 --- a/adept/vlasov1d/pushers/field.py +++ b/adept/vlasov1d/pushers/field.py @@ -109,7 +109,10 @@ def __init__(self, ion_charge, one_over_kx, dv): super(SpectralPoissonSolver, self).__init__() self.ion_charge = ion_charge self.one_over_kx = one_over_kx - self.compute_charges = partial(jnp.trapz, dx=dv, axis=1) + self.dv = dv + + def compute_charges(self, f): + return jnp.sum(f, axis=1) * self.dv def __call__(self, f: jnp.ndarray, prev_ex: jnp.ndarray, dt: jnp.float64): return jnp.real(jnp.fft.ifft(1j * self.one_over_kx * jnp.fft.fft(self.ion_charge - self.compute_charges(f)))) @@ -119,7 +122,10 @@ class AmpereSolver: def __init__(self, cfg): super(AmpereSolver, self).__init__() self.vx = cfg["grid"]["v"] - self.vx_moment = partial(jnp.trapz, dx=cfg["grid"]["dv"], axis=1) + self.dv = cfg["grid"]["dv"] + + def vx_moment(self, f): + return jnp.sum(f, axis=1) * self.dv def __call__(self, f: jnp.ndarray, prev_ex: jnp.ndarray, dt: jnp.float64): return prev_ex - dt * self.vx_moment(self.vx[None, :] * f) @@ -135,8 +141,8 @@ def __init__(self, cfg): def __call__(self, f: jnp.ndarray, prev_ex: jnp.ndarray, dt: jnp.float64): prev_ek = jnp.fft.fft(prev_ex, axis=0) fk = jnp.fft.fft(f, axis=0) - new_ek = prev_ek + self.one_over_ikx * jnp.trapz( - fk * (jnp.exp(-1j * self.kx * dt * self.vx) - 1), dx=self.dv, axis=1 + new_ek = ( + prev_ek + self.one_over_ikx * jnp.sum(fk * (jnp.exp(-1j * self.kx * dt * self.vx) - 1), axis=1) * self.dv ) return jnp.real(jnp.fft.ifft(new_ek)) diff --git a/adept/vlasov1d/pushers/fokker_planck.py b/adept/vlasov1d/pushers/fokker_planck.py index fd89127..1b31156 100644 --- a/adept/vlasov1d/pushers/fokker_planck.py +++ b/adept/vlasov1d/pushers/fokker_planck.py @@ -43,7 +43,9 @@ def __init__(self, cfg): f_mx = np.exp(-self.cfg["grid"]["v"][None, :] ** 2.0 / 2.0) self.f_mx = f_mx / np.trapz(f_mx, dx=self.cfg["grid"]["dv"], axis=1)[:, None] self.dv = self.cfg["grid"]["dv"] - self.vx_moment = partial(jnp.trapz, axis=1, dx=self.dv) + + def vx_moment(self, f_xv): + return jnp.sum(f_xv, axis=1) * self.dv def __call__(self, nu_K, f_xv, dt) -> jnp.ndarray: nu_Kxdt = dt * nu_K[:, None] @@ -59,7 +61,9 @@ def __init__(self, cfg): self.v = self.cfg["grid"]["v"] self.dv = self.cfg["grid"]["dv"] self.ones = jnp.ones((self.cfg["grid"]["nx"], self.cfg["grid"]["nv"])) - self.vx_moment = partial(jnp.trapz, axis=1, dx=self.dv) + + def vx_moment(self, f_xv): + return jnp.sum(f_xv, axis=1) * self.dv def __call__( self, nu: jnp.float64, f_xv: jnp.ndarray, dt: jnp.float64 @@ -85,7 +89,9 @@ def __init__(self, cfg): self.v = self.cfg["grid"]["v"] self.dv = self.cfg["grid"]["dv"] self.ones = jnp.ones((self.cfg["grid"]["nx"], self.cfg["grid"]["nv"])) - self.vx_moment = partial(jnp.trapz, axis=1, dx=self.dv) + + def vx_moment(self, f_xv): + return jnp.sum(f_xv, axis=1) * self.dv def __call__( self, nu: jnp.float64, f_xv: jnp.ndarray, dt: jnp.float64 diff --git a/adept/vlasov1d/storage.py b/adept/vlasov1d/storage.py index 31476e7..651374b 100644 --- a/adept/vlasov1d/storage.py +++ b/adept/vlasov1d/storage.py @@ -115,7 +115,7 @@ def get_field_save_func(cfg, k): if {"t"} == set(cfg["save"][k].keys()): def _calc_moment_(inp): - return jnp.trapz(inp, dx=cfg["grid"]["dv"], axis=1) + return jnp.sum(inp, axis=1) * cfg["grid"]["dv"] def fields_save_func(t, y, args): temp = {"n": _calc_moment_(y["electron"]), "v": _calc_moment_(y["electron"] * cfg["grid"]["v"][None, :])} @@ -198,7 +198,7 @@ def get_default_save_func(cfg): dv = cfg["grid"]["dv"] def _calc_mean_moment_(inp): - return jnp.mean(jnp.trapz(inp, dx=dv, axis=1)) + return jnp.mean(jnp.sum(inp, axis=1) * dv) def save(t, y, args): scalars = { diff --git a/adept/vlasov1d2v/2d.ipynb b/adept/vlasov1d2v/2d.ipynb deleted file mode 100644 index 3442f5f..0000000 --- a/adept/vlasov1d2v/2d.ipynb +++ /dev/null @@ -1,458 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 14, - "id": "65428abb-83a8-4eea-8f8c-9cb7a30a4aee", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "from matplotlib import pyplot as plt\n", - "import lineax as lx\n", - "from jax import vmap, numpy as jnp, jit\n", - "from functools import partial\n", - "from tqdm import tqdm\n", - "import diffrax\n", - "import equinox as eqx\n", - "from time import time\n", - "\n", - "# We'll need this dummy stepper\n", - "class Stepper(diffrax.Euler):\n", - " def step(self, terms, t0, t1, y0, args, solver_state, made_jump):\n", - " del solver_state, made_jump\n", - " y1 = terms.vf(t0, y0, args)\n", - " dense_info = dict(y0=y0, y1=y1)\n", - " return y1, None, dense_info, None, diffrax.RESULTS.successful\n" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "9137509f-cc2b-4d2e-a378-6913a415a1e0", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def get_analytical_2d(diff_coeff, t, v):\n", - " return 1/np.sqrt(4*np.pi*diff_coeff*t)*np.exp(-(v[:, None]**2.+v[None, :]**2.)/4/diff_coeff/t)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "fc7c14d9-8452-47de-906a-4694fc601cc1", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhIAAAGiCAYAAACyHy9XAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA6kElEQVR4nO3de3RU5aH//08u5AK5NHJJCIQkIC0il2ACOYAVPE2JPbj6ZS2lyKFcsjxY2kTAUAqxNuEUa7hEGgUKgku0rRxY/lqURTUWg0jPMYgmclq0QanFpKG5sGwTiDoJmfn9wcnIyCTM7MyeW96vtfZqZ+fZ+3l2WOb5zPM8e+8Qm81mEwAAgAGhvm4AAAAIXAQJAABgGEECAAAYRpAAAACGESQAAIBhBAkAAGAYQQIAABhGkAAAAIYRJAAAgGEECQAAYBhBAgCAALFz506lpaUpKipK2dnZOnXqVI9lf/vb3yorK0tf+cpXNGjQIGVkZOhXv/qV/eednZ1at26dJk6cqEGDBik5OVlLlizRhQsX3GoTQQIAgABw8OBBFRYWqqSkRDU1NZo8ebJyc3PV3NzstPxNN92kH//4x6qqqtIf//hH5eXlKS8vT6+++qok6dNPP1VNTY1+8pOfqKamRr/97W919uxZffvb33arXSG8tAsAAP+XnZ2tqVOnaseOHZIkq9WqlJQUPfjgg1q/fr1L57jttts0d+5cbdy40enP3377bU2bNk0ff/yxRo0a5dI5w11rvm9YrVZduHBBsbGxCgkJ8XVzAAB+zGaz6dKlS0pOTlZoqHkD7p9//rk6Ojr6fB6bzXZd3xYZGanIyMjrynZ0dKi6ulpFRUX2faGhocrJyVFVVZVLdR07dkxnz57V5s2beyzX2tqqkJAQfeUrX3H5Ovw6SFy4cEEpKSm+bgYAIIDU19dr5MiRppz7888/16hRg9TSYu3zuWJiYnT58mWHfSUlJdqwYcN1ZS9evKiuri4lJiY67E9MTFRtbW2PdbS2tmrEiBGyWCwKCwvTL37xC33zm990Wvbzzz/XunXrtHDhQsXFxbl8HX4dJGJjYyVJs4csUXhohI9bAwDwZ1esHTp+8Zf2vsMMHR0dammx6vhbwxQTY3yk/PJlm2ZnN6u+vt6h03Y2GtEXsbGxOn36tC5fvqzKykoVFhZq9OjRmj17tkO5zs5Ofec735HNZtOuXbvcqsOvg0T3kE94aARBAgDgEm9MhcfEhCgmti/TJ1dHNOLi4lz69j9kyBCFhYWpqanJYX9TU5OSkpJ6PC40NFQ333yzJCkjI0N//vOfVVpa6hAkukPExx9/rGPHjrk1GiFx1wYAAH4vIiJCmZmZqqystO+zWq2qrKzU9OnTXT6P1WqVxWKxf+4OER9++KFee+01DR482O22+fWIBAAAuKqwsFBLly5VVlaWpk2bpvLycrW3tysvL0+StGTJEo0YMUKlpaWSpNLSUmVlZWnMmDGyWCx6+eWX9atf/co+ddHZ2al7771XNTU1OnLkiLq6utTY2Cjp6q2jERGuzQQQJAAACAALFixQS0uLiouL1djYqIyMDFVUVNgXYNbV1TncrdLe3q4f/OAH+tvf/qbo6GiNGzdOv/71r7VgwQJJUkNDgw4fPizp6rTHtV5//fXr1lH0xK+fI9HW1qb4+HjlDPsP1kgAAHp1xdqh15qfVmtrq9vz/K7q7pfeeS+xT2skLl+yKuvWJlPb6i2mr5FoaGjQd7/7XQ0ePFjR0dGaOHGi3nnnHbOrBQAAXmDq1MY//vEPzZw5U3feeadeeeUVDR06VB9++KESEhLMrBYAAHiJqUFi8+bNSklJ0b59++z70tPTzawSAAB4kalTG4cPH1ZWVpbmz5+vYcOGacqUKdq7d2+P5S0Wi9ra2hw2AADgv0wNEh999JF27dqlsWPH6tVXX9X3v/99rVy5Us8995zT8qWlpYqPj7dvPB4bAAD/ZupdGxEREcrKytKbb75p37dy5Uq9/fbbTl8yYrFYHB6U0dbWppSUFO7aAADcEHdt+IapIxLDhw/X+PHjHfbdcsstqqurc1o+MjLS/rhQVx8bCgAAfMfUIDFz5kydPXvWYd8HH3yg1NRUM6sFAABeYmqQeOihh3Ty5Ek99thjOnfunPbv3689e/YoPz/fzGoBAICXmBokpk6dqkOHDum//uu/NGHCBG3cuFHl5eVatGiRmdUCAAAvMf1dG3fffbfuvvtus6sBAAA+wGvEAQCAYQQJAABgGEECAAAYRpAAAACGESQAAIBhBAkAAGAYQQIAABhGkAAAAIYRJAAAgGEECQAAYBhBAgAAGEaQAAAAhhEkAACAYQQJAABgGEECAAAYRpAAAACGESQAAIBhBAkAAGAYQQIAABhGkAAAAIYRJAAAgGEECQAAYBhBAgAAGEaQAAAAhhEkAAAIEDt37lRaWpqioqKUnZ2tU6dO9Vh27969+vrXv66EhAQlJCQoJyfnuvKXL19WQUGBRo4cqejoaI0fP167d+92q00ECQAAAsDBgwdVWFiokpIS1dTUaPLkycrNzVVzc7PT8sePH9fChQv1+uuvq6qqSikpKZozZ44aGhrsZQoLC1VRUaFf//rX+vOf/6zVq1eroKBAhw8fdrldBAkAAALAtm3btHz5cuXl5dlHDgYOHKhnnnnGafnnn39eP/jBD5SRkaFx48bp6aefltVqVWVlpb3Mm2++qaVLl2r27NlKS0vTAw88oMmTJ/c60vFlBAkAAHykra3NYbNYLE7LdXR0qLq6Wjk5OfZ9oaGhysnJUVVVlUt1ffrpp+rs7NRNN91k3zdjxgwdPnxYDQ0Nstlsev311/XBBx9ozpw5Ll9DuMslAQCAJOnFS5MVZRtg+PjPL3dK+r1SUlIc9peUlGjDhg3Xlb948aK6urqUmJjosD8xMVG1tbUu1blu3TolJyc7hJHt27frgQce0MiRIxUeHq7Q0FDt3btXd9xxh8vXQpAAAMBH6uvrFRcXZ/8cGRlpSj2bNm3SgQMHdPz4cUVFRdn3b9++XSdPntThw4eVmpqqEydOKD8//7rA0RuCBAAAPhIXF+cQJHoyZMgQhYWFqampyWF/U1OTkpKSej22rKxMmzZt0muvvaZJkybZ93/22Wd6+OGHdejQIc2dO1eSNGnSJJ0+fVplZWUuBwnWSAAA4OciIiKUmZnpsFCye+Hk9OnTezxuy5Yt2rhxoyoqKpSVleXws87OTnV2dio01DEKhIWFyWq1utw2RiQAAAgAhYWFWrp0qbKysjRt2jSVl5ervb1deXl5kqQlS5ZoxIgRKi0tlSRt3rxZxcXF2r9/v9LS0tTY2ChJiomJUUxMjOLi4jRr1iytXbtW0dHRSk1N1RtvvKFf/vKX2rZtm8vtIkgAABAAFixYoJaWFhUXF6uxsVEZGRmqqKiwL8Csq6tzGF3YtWuXOjo6dO+99zqc59oFnQcOHFBRUZEWLVqkTz75RKmpqfrZz36mFStWuNwuggQAAAGioKBABQUFTn92/Phxh8/nz5+/4fmSkpK0b9++PrWJNRIAAMAwggQAADCMIAEAAAwjSAAAAMMIEgAAwDCCBAAAMIwgAQAADCNIAAAAwwgSAADAMIIEAAAwjCABAAAMI0gAAADDvBYkNm3apJCQEK1evdpbVQIAAJN5JUi8/fbbeuqppzRp0iRvVAcAALzE9CBx+fJlLVq0SHv37lVCQoLZ1QEAAC8yPUjk5+dr7ty5ysnJuWFZi8WitrY2hw0AAPivcDNPfuDAAdXU1Ojtt992qXxpaan+8z//08wmAQAADzJtRKK+vl6rVq3S888/r6ioKJeOKSoqUmtrq32rr683q3kAAMADTBuRqK6uVnNzs2677Tb7vq6uLp04cUI7duyQxWJRWFiYwzGRkZGKjIw0q0kAAMDDTAsS3/jGN/SnP/3JYV9eXp7GjRundevWXRciAABA4DEtSMTGxmrChAkO+wYNGqTBgwdftx8AAAQmnmwJAAAMM/WujS87fvy4N6sDAAAmY0QCAAAYRpAAAACGESQAAIBhBAkAAGAYQQIAABhGkAAAAIYRJAAAgGEECQAAYBhBAgAAGEaQAAAAhhEkAACAYQQJAABgGEECAIAAsXPnTqWlpSkqKkrZ2dk6depUj2X37t2rr3/960pISFBCQoJycnJ6Lb9ixQqFhISovLzcrTYRJAAACAAHDx5UYWGhSkpKVFNTo8mTJys3N1fNzc1Oyx8/flwLFy7U66+/rqqqKqWkpGjOnDlqaGi4ruyhQ4d08uRJJScnu90uggQAAAFg27ZtWr58ufLy8jR+/Hjt3r1bAwcO1DPPPOO0/PPPP68f/OAHysjI0Lhx4/T000/LarWqsrLSoVxDQ4MefPBBPf/88xowYIDb7SJIAADgI21tbQ6bxWJxWq6jo0PV1dXKycmx7wsNDVVOTo6qqqpcquvTTz9VZ2enbrrpJvs+q9WqxYsXa+3atbr11lsNXUO4oaMAAOjHXm/6qsIvRxo+/kq7RdLvlZKS4rC/pKREGzZsuK78xYsX1dXVpcTERIf9iYmJqq2tdanOdevWKTk52SGMbN68WeHh4Vq5cqXb19CNIAEAgI/U19crLi7O/jky0ng46c2mTZt04MABHT9+XFFRUZKk6upqPfHEE6qpqVFISIjhczO1AQCAj8TFxTlsPQWJIUOGKCwsTE1NTQ77m5qalJSU1GsdZWVl2rRpk37/+99r0qRJ9v1/+MMf1NzcrFGjRik8PFzh4eH6+OOPtWbNGqWlpbl8DQQJAAD8XEREhDIzMx0WSnYvnJw+fXqPx23ZskUbN25URUWFsrKyHH62ePFi/fGPf9Tp06ftW3JystauXatXX33V5bYxtQEAQAAoLCzU0qVLlZWVpWnTpqm8vFzt7e3Ky8uTJC1ZskQjRoxQaWmppKvrH4qLi7V//36lpaWpsbFRkhQTE6OYmBgNHjxYgwcPdqhjwIABSkpK0te+9jWX20WQAAAgACxYsEAtLS0qLi5WY2OjMjIyVFFRYV+AWVdXp9DQLyYadu3apY6ODt17770O5+lpQadRBAkAAAJEQUGBCgoKnP7s+PHjDp/Pnz/v9vmNHMMaCQAAYBhBAgAAGEaQAAAAhhEkAACAYSy2BPxUx7iRho+NqP2bB1sCAD0jSAA+0peg0NdzEzQAeApBAvACM0ODEc7aQ7gAYARBAjCBvwUHV3y5zQQLAK4gSAAeEIjB4UYIFgBcQZAADArG8NCba6+XUAGgG0ECcFN/CxDOdP8OCBQACBKACwgPzjFKAYAgAfSCAOE6RimA/okgAThBgDCOQAH0LwQJ4BoECM8hUAD9A0ECEAHCTAQKILgRJNCvESC8h0ABBCfe/ol+ixDhGx3jRvK7B4IIQQL9Dh2Zf+DfAAgOTG2g36Dj8j9MdwCBjyCBfiEQQ0TrmEjDx8b/xeLBlpivY9xIwgQQoAgSCHr+HCL6EhaMntdfQwajE0BgIkggaPljgDArOPS1Df4ULhidAAILQQJByV9ChD8EB1dc205/CBWECSBwmHrXRmlpqaZOnarY2FgNGzZM8+bN09mzZ82sEvB5iGgdE2nfApG/tN/X/44AXGNqkHjjjTeUn5+vkydP6ujRo+rs7NScOXPU3t5uZrXox3zV+fhL5+tpvr4ubtUF/J+pUxsVFRUOn5999lkNGzZM1dXVuuOOO8ysGv2MLwNEf9F9rb6Y+mCqA/BfXl0j0draKkm66aabnP7cYrHIYvnij1RbW5tX2oXA5osQ0Z8CxJf5KlAQJgD/5LUnW1qtVq1evVozZ87UhAkTnJYpLS1VfHy8fUtJSfFW8xCgvB0ignH6wihf/C6Y5gD8j9eCRH5+vs6cOaMDBw70WKaoqEitra32rb6+3lvNQwDyZqdCgOiZt383hAnAv3hlaqOgoEBHjhzRiRMnNHJkz38EIiMjFRnJH2vcmLc6E8KD67w55cE0B+A/TB2RsNlsKigo0KFDh3Ts2DGlp6ebWR36CUKEf/PW742RCcA/mDoikZ+fr/379+ull15SbGysGhsbJUnx8fGKjo42s2oEKW90Hr4MEJdSQ0w5b+zHNlPO2xNvjU4wMgH4nqlBYteuXZKk2bNnO+zft2+fli1bZmbVCELBFiLMCg2u1OWtYNE6JpIwAQQ5U4OEzebdb0GAUd4KEN4MD73xZrDwxugEYQLwHd61gYBg5miE2SHCX8JDb65to1mhwuzRCcIE4Bteu/0TMCoQQ8Sl1BD7FmjMbDcLWIG+2blzp9LS0hQVFaXs7GydOnWqx7J79+7V17/+dSUkJCghIUE5OTnXlbfZbCouLtbw4cMVHR2tnJwcffjhh261iSABvxZoISJQw4MzZl2LmWGCOzkQzA4ePKjCwkKVlJSopqZGkydPVm5urpqbm52WP378uBYuXKjXX39dVVVVSklJ0Zw5c9TQ0GAvs2XLFj355JPavXu33nrrLQ0aNEi5ubn6/PPPXW5XiM2PFzK0tbUpPj5eOcP+Q+GhEb5uDrwskEJEsISH3pgx5WHWVAdTHP3TFWuHXmt+Wq2trYqLizOlju5+aeZLBQofZPzvyJV2i/7n/+1QfX29Q1t7e55Sdna2pk6dqh07dki6+sTolJQUPfjgg1q/fv0N6+zq6lJCQoJ27NihJUuWyGazKTk5WWvWrNEPf/hDSVdfZZGYmKhnn31W9913n0vXwhoJ9DueDBH9IUB0675WTwYKs9ZNsF4CZqu7MESh0VGGj7d+dvUb/5dfBVFSUqINGzZcV76jo0PV1dUqKiqy7wsNDVVOTo6qqqpcqvPTTz9VZ2en/X1Xf/3rX9XY2KicnBx7mfj4eGVnZ6uqqooggcBm1miEp0JEfwoQX+bpQOGNW0QBf+VsRMKZixcvqqurS4mJiQ77ExMTVVtb61Jd69atU3Jysj04dD/bydk5u3/mCoIE/A4honeWUR32/x9Z57spv0upIX4dJhiVQCCIi4szbRrmWps2bdKBAwd0/PhxRUUZH0lxhiABv+LPIcIbAeLakOCp8maGDU+OThAmgJ4NGTJEYWFhampqctjf1NSkpKSkXo8tKyvTpk2b9Nprr2nSpEn2/d3HNTU1afjw4Q7nzMjIcLlt3LWBoOfPIcIyqsNhC9Q6PPX74fZQwLmIiAhlZmaqsrLSvs9qtaqyslLTp0/v8bgtW7Zo48aNqqioUFZWlsPP0tPTlZSU5HDOtrY2vfXWW72e88sYkYDfMGM0wh9DhFmduZH6PTla4cmpDk9iVALBorCwUEuXLlVWVpamTZum8vJytbe3Ky8vT5K0ZMkSjRgxQqWlpZKkzZs3q7i4WPv371daWpp93UNMTIxiYmIUEhKi1atX69FHH9XYsWOVnp6un/zkJ0pOTta8efNcbhdBAkHL30KErwOEM54OFZ6Y6mCKA3BuwYIFamlpUXFxsRobG5WRkaGKigr7Ysm6ujqFhn4x0bBr1y51dHTo3nvvdTjPtXeG/OhHP1J7e7seeOAB/fOf/9Ttt9+uiooKt9ZR8BwJ+AVPj0b0NUR4KkD4Y3i4EU+NUvR1dMLTYYIgEfy8+RyJlF0b+nz7Z/33N5jaVm9hjQR8jhDhXzy1lqKvv0dPr5fgqZeAOQgSwDU8ESLMXNToTcEYJgB4HkECPuVPoxF97fSCJUBcyxPX5OvnblyLUQnA8wgSCBq+DhHBrK+Boi+/X0YlAP/GXRvwmWD4duiNAJE2ssWt8uf/NtSklly9XqOLMftye6gn7+TgDg7AswgSCAq+GI0wI0S4GxpcOYeng4WvwgQA/0SQgE94cjQi0EOEJ8KDq+f3VKjoS5gwilEJwD8RJNBv+TJEmB0eXKm3r6HCaJjwlykOAJ7BYkt4nT+MRvgqRKSNbPFZiPgyT7TF6O/DH+7kCIY1OoA/IEgALvJEiPBHfQ0U3g4T3MUB+BeCBAKWN0cj+hIi/GkUoje+CBO+xqgE0HcECXiVr/9w+yJEBJK+hB4jvydGJYDAR5BAQPJWR2I0RATKKERPvBkmAAQ2ggT6DW8t8AvkAHEtb4UJX49K+HqUDAh0BAl4jaf+YPvzaESwhIhu3roef7iLA4AxPEcC/YK7HZW/hIhvJtW6fczRxnEebUPayBa3nznhiwdWAfANggQCir8usvNkiDASHno63lOhwhthwsiDqjz1gCqedAkYR5CAV/hyHtrs0QhPhIi+hgdXztvXUGEkTAAIfqyRAK4RTCHCWT19rcvd6+UuDiD4ESQQMIxMa/jzIj5PdOxG6+0LMxdgGvn38tfpLqC/IEgA/8eboxG+CBC+qj9QRiW4DRQwhiAB0wXjH+hADhHd+jIi4m+jEgB8hyCBoOWPHZK/hIhreaNNZo9KML0B+A5BAgHB7I7CnY7O6LdxfwwR3Yy0LdgevgXAGIIE4AX+HCL8ka9Gk4JxGg4wG0ECQcmdjsjs0YhACRFmj0oEyqJLAO4hSMBUfMMLLIESepxhnQTgGwQJ+L1A7iACuWN2FWslgP6NIAG4yN0OM1BDhJntdmd6wx/vugFwPYIE+jXm7QGgbwgSCDp8k+07d0clmN4A+i+CBOCC/jKtARYIA+4iSAAAAMPCfd0AAK67N67mun3/X9ttptT1zaRaHW0c5/HzWkZ1KLIuwuPnla7e4RP/F4sp5wbgHEECCADOAsSXf2ZWoACA3nhlamPnzp1KS0tTVFSUsrOzderUKW9UCx/rr3PNvlof0VvYABAc3OlP33vvPd1zzz1KS0tTSEiIysvLnZZraGjQd7/7XQ0ePFjR0dGaOHGi3nnnHZfbZHqQOHjwoAoLC1VSUqKamhpNnjxZubm5am5uNrtqoFeBcusnAQGA5H5/+umnn2r06NHatGmTkpKSnJb5xz/+oZkzZ2rAgAF65ZVX9P777+vxxx9XQkKCy+0yPUhs27ZNy5cvV15ensaPH6/du3dr4MCBeuaZZ64ra7FY1NbW5rChfwvkp1oCwI18uc+zWHpe4+NOfypJU6dO1datW3XfffcpMtL539LNmzcrJSVF+/bt07Rp05Senq45c+ZozJgxLl+DqUGio6ND1dXVysnJ+aLC0FDl5OSoqqrquvKlpaWKj4+3bykpKWY2DwAAQyLqIxRZZ3yLqL+64DglJcWh3ystLXVan7v9qasOHz6srKwszZ8/X8OGDdOUKVO0d+9et85hapC4ePGiurq6lJiY6LA/MTFRjY2N15UvKipSa2urfauvrzezeQgArMAHEMzq6+sd+r2ioiKn5dztT1310UcfadeuXRo7dqxeffVVff/739fKlSv13HPPuXwOv7prIzIyssfhFwAAgk1cXJzi4uJ8Vr/ValVWVpYee+wxSdKUKVN05swZ7d69W0uXLnXpHKaOSAwZMkRhYWFqampy2N/U1NTjwg/AW8x6loGncVsnALP60+HDh2v8+PEO+2655RbV1dW5fA5Tg0RERIQyMzNVWVlp32e1WlVZWanp06ebWTX8QETt33zdBJ8w4yFOriBwAMHLrP505syZOnv2rMO+Dz74QKmpqS6fw/SpjcLCQi1dulRZWVmaNm2aysvL1d7erry8PLOrBoJGd0jw5pMtAfiXG/WnS5Ys0YgRI+wLNjs6OvT+++/b/39DQ4NOnz6tmJgY3XzzzZKkhx56SDNmzNBjjz2m73znOzp16pT27NmjPXv2uNwu04PEggUL1NLSouLiYjU2NiojI0MVFRXXLRgBcGPeDA1mjayYOaXE4lwEsxv1p3V1dQoN/WKi4cKFC5oyZYr9c1lZmcrKyjRr1iwdP35c0tVbRA8dOqSioiL99Kc/VXp6usrLy7Vo0SKX2+WVxZYFBQUqKCjwRlUAAASt3vrT7nDQLS0tTTab7YbnvPvuu3X33XcbbhNv/wRccP5vQ90q76t1Eui7/rq2BzCKIIGgE/vxjRM4euduEHI3aAEIHgQJ9GuBcgsoAPgrggTgov4yvWFmu90JbowsAYGBIAG/F8gr8QM1TLiDaQ2gfyNIwFQsXAssgRx8AjlwAoGMIIGg5M6wuDvD7Ua+fQdK52ykne78PliPAgQnggTgBYESJvyFr9ZHMIIGuI8ggYBg9rC12aMSkn+HCbNHIwAEL4IEgpY/rvr3xzDhjTaZPa3B+gjAdwgSMF0wDhf35du4v4SJo43jDLfFzNEIfwyAAHpGkAD+j7vfmgM5THiz/kBZZBmMgRfwBoIEAoaR4Wt//nbblxGBvtbbF/42GsG0BuBbXnn7JxAoIusiZBnV4XL5838bqrSRLX2qs7tj/2ZSbZ/O42o9feFuiAiU0QgAxhEk4BURtX9Tx7iRPqk79mObLqWGuFzeF2FCMidQeHLEg7s0ADhDkEBAif+LRa1jIn3djOt4KkxIjp2/kVBhxnSJkRDh7miEL6c1WB8BGEeQQL9g9qiE5Nkw0c3XizIl74QIAIGLxZbwGk996/PW4jojnWGwDf9763r8eVEsgN4RJNBveKuzCpYwYfQ6vDGlITGtAfgLggQCkj+PSkhXO+FADhTeChEAAh9BAl7l629/Rr799qVzDLQw0ZcAZOT35OvRCAB9R5BAwDLamfgiTARCoOhLGwN1JMLXwRYIBgQJwEV97Sz9NUz0NegY/b0wGgEEB4IEvM6T3wK9OSoheSZM+Eug8ERbAjlEMBoBeAbPkUC/5e6zJboZecbEl13bgXv62ROu1ttX3g4RAPwTQQI+4clHZvflaZe+DBPdzA4VZoyA+GJNBKMRgH8iSCAoBHqY6Oas03cnXHhj2qQvIYLRCCD4ECTgM758kZendHeqng4U1/KXNRV9HYXoS4hgNALwXyy2RNDoS2fT12/KgXr7o6uCJUQA8DyCBHzK098OfR0mgi1QeOKa/Gk6g9EIwPMIEsA1PNHpBUug8MQ19PX3yWgE4P8IEvA5fxqVkDz3DTpQA4Wn2u1vIYLRCMAcBAn4BX8ME/0tUHiynf4WIgCYh7s2ELT6cktoN6O3hjrjjTs83OXpgOOJ8GVGiGA0AjAPIxLwG2b8sfdEp+TpxYLd3/x9NUphVv3+tKjyWoQIwFwECQQ9T4UJMzrKazt1s4KFN+rw1O+GKQ2gdzt37lRaWpqioqKUnZ2tU6dO9Vj2vffe0z333KO0tDSFhISovLz8ujKlpaWaOnWqYmNjNWzYMM2bN09nz551q01MbcCvmPWQKk9Mc0ienepwJhDWUlzLk+GKKQ2gdwcPHlRhYaF2796t7OxslZeXKzc3V2fPntWwYcOuK//pp59q9OjRmj9/vh566CGn53zjjTeUn5+vqVOn6sqVK3r44Yc1Z84cvf/++xo0aJBL7WJEAn7HrD/+nuqozBqdCDSECMC7tm3bpuXLlysvL0/jx4/X7t27NXDgQD3zzDNOy0+dOlVbt27Vfffdp8hI51+kKioqtGzZMt16662aPHmynn32WdXV1am6utrldhEk4Jf8PUxI/rsmwGyeDlJMZ6A/a2trc9gsFuf/PXR0dKi6ulo5OTn2faGhocrJyVFVVZXH2tPa2ipJuummm1w+hqkN9DuemuaQvggTZk53+AszgpNZIYLRCJgttt6msAjj/010dVw9NiUlxWF/SUmJNmzYcF35ixcvqqurS4mJiQ77ExMTVVtba7gd17JarVq9erVmzpypCRMmuHwcQQJ+y8yXenkyTEjBHSgCKUBIhAgElvr6esXFxdk/9zQF4Q35+fk6c+aM/vu//9ut4wgS8GuBFCak4AoUZk3dECKAL8TFxTkEiZ4MGTJEYWFhampqctjf1NSkpKSkPrejoKBAR44c0YkTJzRypHt/c1kjAb9nZudgVqfWvY4g0NZRmN1u1kMAxkRERCgzM1OVlZX2fVarVZWVlZo+fbrh89psNhUUFOjQoUM6duyY0tPT3T4HIxIICGaPTEjy+OhEt2s7ZX8dqfBG4DE7RDAagWBXWFiopUuXKisrS9OmTVN5ebna29uVl5cnSVqyZIlGjBih0tJSSVcXaL7//vv2/9/Q0KDTp08rJiZGN998s6Sr0xn79+/XSy+9pNjYWDU2NkqS4uPjFR0d7VK7CBLA/zFjquPL/CVUeHOkxBujEIQI9AcLFixQS0uLiouL1djYqIyMDFVUVNgXYNbV1Sk09IuJhgsXLmjKlCn2z2VlZSorK9OsWbN0/PhxSdKuXbskSbNnz3aoa9++fVq2bJlL7SJIIGCYOSrRzRthopuzztyMcOHL6RVCBOBZBQUFKigocPqz7nDQLS0tTTZb7//93+jnriBIIKB4K0xI5k119CbQ1lT0xFtrIQgRgO+Zttjy/Pnzuv/++5Wenq7o6GiNGTNGJSUl6ujwnzcfIjB5q/OI/4uFxYEGECKA/sW0EYna2lpZrVY99dRTuvnmm3XmzBktX75c7e3tKisrM6ta9BPeGJno5s3pjkDmzdBFiAD8h2lB4q677tJdd91l/zx69GidPXtWu3bt6jFIWCwWh8eDtrW1mdU8BAFvhwnJN9Md/s7bozaECMC/ePU5Eq2trb0+v7u0tFTx8fH27cuPDgW+zNudCtMdX/DF74IQAfgfrwWJc+fOafv27fre977XY5mioiK1trbat/r6em81DwHMF51Lfw4Uvrp2QgTgn9wOEuvXr1dISEiv25dfINLQ0KC77rpL8+fP1/Lly3s8d2RkpP1xoa4+NhSQrnYyvgwU/SFU+PI6CRGA/3J7jcSaNWtu+JCK0aNH2///hQsXdOedd2rGjBnas2eP2w0E3OHNdRNfFozrKHwdkAgQgP9zO0gMHTpUQ4cOdalsQ0OD7rzzTmVmZmrfvn0OT9wCzOLLMCE5dr6BGCp8HR66ESKAwGDaXRsNDQ2aPXu2UlNTVVZWppaWFvvPPPGmMqA3vg4T3b7cKftjsPCX4HAtQgQQOEwLEkePHtW5c+d07ty5615J6olHcgI30t0Z+UOg6OYPwcIfg8O1CBFAYDEtSCxbtszlF34AZvKX0QlneuvU+xIy/D0sOEOAAAIT79pAv+CPoxM3EohhwChCBBC4WP2IfoUOy7/46rZdAJ5DkEC/Q+flH/g3AIIDQQL9Fh2ZbxDkgODCGgn0a4G4diJQER6A4ESQAESgMBMBAghuBAngGgQKzyFAAP0DQQJwgkBhHAEC6F8IEkAvCBSuI0AA/RNBAnDBtZ0koeILhAcABAnATYQKAgSALxAkgD7oT6GC8ADAGYIE4CHBFioIDgBcQZAATPDlTjgQggXBAYARBAnAC5x10r4MF4QGAJ5CkAB8xJXO3EjYICQA8CaCBODHCAUA/B1v/wQAAIYRJAAAgGEECQAAYBhBAgAAGEaQAAAAhhEkAACAYQQJAAACxM6dO5WWlqaoqChlZ2fr1KlTvZZ/4YUXNG7cOEVFRWnixIl6+eWXHX5++fJlFRQUaOTIkYqOjtb48eO1e/dut9pEkAAAIAAcPHhQhYWFKikpUU1NjSZPnqzc3Fw1Nzc7Lf/mm29q4cKFuv/++/Xuu+9q3rx5mjdvns6cOWMvU1hYqIqKCv3617/Wn//8Z61evVoFBQU6fPiwy+0iSAAAEAC2bdum5cuXKy8vzz5yMHDgQD3zzDNOyz/xxBO66667tHbtWt1yyy3auHGjbrvtNu3YscNe5s0339TSpUs1e/ZspaWl6YEHHtDkyZNvONJxLYIEAAA+0tbW5rBZLBan5To6OlRdXa2cnBz7vtDQUOXk5KiqqsrpMVVVVQ7lJSk3N9eh/IwZM3T48GE1NDTIZrPp9ddf1wcffKA5c+a4fA08IhsAADfF/dWi8PAQw8dfuXI1MKSkpDjsLykp0YYNG64rf/HiRXV1dSkxMdFhf2Jiompra53W0djY6LR8Y2Oj/fP27dv1wAMPaOTIkQoPD1doaKj27t2rO+64w+VrIUgAAOAj9fX1iouLs3+OjIz0av3bt2/XyZMndfjwYaWmpurEiRPKz89XcnLydaMZPSFIAADgI3FxcQ5BoidDhgxRWFiYmpqaHPY3NTUpKSnJ6TFJSUm9lv/ss8/08MMP69ChQ5o7d64kadKkSTp9+rTKyspcDhKskQAAwM9FREQoMzNTlZWV9n1Wq1WVlZWaPn2602OmT5/uUF6Sjh49ai/f2dmpzs5OhYY6RoGwsDBZrVaX28aIBAAAAaCwsFBLly5VVlaWpk2bpvLycrW3tysvL0+StGTJEo0YMUKlpaWSpFWrVmnWrFl6/PHHNXfuXB04cEDvvPOO9uzZI+nqaMisWbO0du1aRUdHKzU1VW+88YZ++ctfatu2bS63iyABAEAAWLBggVpaWlRcXKzGxkZlZGSooqLCvqCyrq7OYXRhxowZ2r9/vx555BE9/PDDGjt2rF588UVNmDDBXubAgQMqKirSokWL9Mknnyg1NVU/+9nPtGLFCpfbFWKz2Wyeu0zPamtrU3x8vHKG/YfCQyN83RwAgB+7Yu3Qa81Pq7W11aV1B0Z090t33F6s8PAow+e5cuVznfjvn5raVm9hjQQAADCMIAEAAAwjSAAAAMMIEgAAwDCCBAAAMIwgAQAADCNIAAAAwwgSAADAMIIEAAAwjCABAAAMI0gAAADDCBIAAMAwrwQJi8WijIwMhYSE6PTp096oEgAAeIFXgsSPfvQjJScne6MqAADgRaYHiVdeeUW///3vVVZWZnZVAADAy8LNPHlTU5OWL1+uF198UQMHDrxheYvFIovFYv/c1tZmZvMAAEAfmTYiYbPZtGzZMq1YsUJZWVkuHVNaWqr4+Hj7lpKSYlbzAACAB7gdJNavX6+QkJBet9raWm3fvl2XLl1SUVGRy+cuKipSa2urfauvr3e3eQAAwIvcntpYs2aNli1b1muZ0aNH69ixY6qqqlJkZKTDz7KysrRo0SI999xz1x0XGRl5XXkAAOC/3A4SQ4cO1dChQ29Y7sknn9Sjjz5q/3zhwgXl5ubq4MGDys7OdrdaAADgh0xbbDlq1CiHzzExMZKkMWPGaOTIkWZVCwAAvIgnWwIAAMNMvf3zWmlpabLZbN6qDgAAeAEjEgAAwDCCBAAAMIwgAQAADCNIAAAAwwgSAADAMIIEAAAwjCABAAAMI0gAAADDCBIAAMAwggQAADCMIAEAAAwjSAAAAMMIEgAABIidO3cqLS1NUVFRys7O1qlTp3ot/8ILL2jcuHGKiorSxIkT9fLLL/dYdsWKFQoJCVF5eblbbSJIAAAQAA4ePKjCwkKVlJSopqZGkydPVm5urpqbm52Wf/PNN7Vw4ULdf//9evfddzVv3jzNmzdPZ86cua7soUOHdPLkSSUnJ7vdLoIEAAABYNu2bVq+fLny8vI0fvx47d69WwMHDtQzzzzjtPwTTzyhu+66S2vXrtUtt9yijRs36rbbbtOOHTscyjU0NOjBBx/U888/rwEDBrjdLoIEAAA+0tbW5rBZLBan5To6OlRdXa2cnBz7vtDQUOXk5KiqqsrpMVVVVQ7lJSk3N9ehvNVq1eLFi7V27Vrdeuuthq4h3NBRAAD0YxEfXFB4aITh40OtHZKklJQUh/0lJSXasGHDdeUvXryorq4uJSYmOuxPTExUbW2t0zoaGxudlm9sbLR/3rx5s8LDw7Vy5UojlyGJIAEAgM/U19crLi7O/jkyMtJrdVdXV+uJJ55QTU2NQkJCDJ+HqQ0AAHwkLi7OYespSAwZMkRhYWFqampy2N/U1KSkpCSnxyQlJfVa/g9/+IOam5s1atQohYeHKzw8XB9//LHWrFmjtLQ0l6+BIAEAgJ+LiIhQZmamKisr7fusVqsqKys1ffp0p8dMnz7dobwkHT161F5+8eLF+uMf/6jTp0/bt+TkZK1du1avvvqqy21jagMAgABQWFiopUuXKisrS9OmTVN5ebna29uVl5cnSVqyZIlGjBih0tJSSdKqVas0a9YsPf7445o7d64OHDigd955R3v27JEkDR48WIMHD3aoY8CAAUpKStLXvvY1l9tFkAAAIAAsWLBALS0tKi4uVmNjozIyMlRRUWFfUFlXV6fQ0C8mGmbMmKH9+/frkUce0cMPP6yxY8fqxRdf1IQJEzzarhCbzWbz6Bk9qK2tTfHx8coZ9h99Wh0LAAh+V6wdeq35abW2tjosYPQkT/VL3mirt7BGAgAAGEaQAAAAhhEkAACAYQQJAABgGEECAAAYRpAAAACGESQAAIBhBAkAAGAYQQIAABhGkAAAAIYRJAAAgGEECQAAYBhBAgAAGEaQAAAAhhEkAACAYQQJAABgGEECAAAYRpAAAACGESQAAIBhBAkAAGAYQQIAABhGkAAAAIYRJAAAgGEECQAAYJipQeJ3v/udsrOzFR0drYSEBM2bN8/M6gAAgJeFm3Xi3/zmN1q+fLkee+wx/eu//quuXLmiM2fOmFUdAADwAVOCxJUrV7Rq1Spt3bpV999/v33/+PHjzagOAAD4iClTGzU1NWpoaFBoaKimTJmi4cOH61vf+tYNRyQsFova2tocNgAA4L9MCRIfffSRJGnDhg165JFHdOTIESUkJGj27Nn65JNPejyutLRU8fHx9i0lJcWM5gEAAA9xK0isX79eISEhvW61tbWyWq2SpB//+Me65557lJmZqX379ikkJEQvvPBCj+cvKipSa2urfauvr+/b1QEAAFO5tUZizZo1WrZsWa9lRo8erb///e+SHNdEREZGavTo0aqrq+vx2MjISEVGRrrTJAAA4ENuBYmhQ4dq6NChNyyXmZmpyMhInT17VrfffrskqbOzU+fPn1dqaqqxlgIAAL9jyl0bcXFxWrFihUpKSpSSkqLU1FRt3bpVkjR//nwzqgQAAD5g2nMktm7dqvDwcC1evFifffaZsrOzdezYMSUkJJhVJQAA8DLTgsSAAQNUVlamsrIys6oAAAA+xrs2AACAYQQJAAACxM6dO5WWlqaoqChlZ2fr1KlTvZZ/4YUXNG7cOEVFRWnixIl6+eWXHX5us9lUXFys4cOHKzo6Wjk5Ofrwww/dahNBAgCAAHDw4EEVFhaqpKRENTU1mjx5snJzc9Xc3Oy0/JtvvqmFCxfq/vvv17vvvqt58+Zp3rx5Dk+Z3rJli5588knt3r1bb731lgYNGqTc3Fx9/vnnLrcrxGaz2fp8dSZpbW3VV77yFc0eskThoRG+bg4AwI9dsXbo+MVf6p///Kfi4+NNqaOtrU3x8fGaPXSJwkOM90tXbB063vJL1dfXKy4uzr6/t+cpZWdna+rUqdqxY4ckyWq1KiUlRQ8++KDWr19/XfkFCxaovb1dR44cse/7l3/5F2VkZGj37t2y2WxKTk7WmjVr9MMf/lDS1X43MTFRzz77rO677z7XLsbmx+rr622S2NjY2NjYXN7q6+tN65c+++wzW1JSkkfaGRMTc92+kpISp/VaLBZbWFiY7dChQw77lyxZYvv2t7/t9JiUlBTbz3/+c4d9xcXFtkmTJtlsNpvtL3/5i02S7d1333Uoc8cdd9hWrlzp8u/EtLs2PCE5OVn19fWKjY1VSEiIS8e0tbUpJSXlupQX7Lhurrs/4Lq57t7YbDZdunRJycnJprUpKipKf/3rX9XR0dHnc9lstuv6tp5GIy5evKiuri4lJiY67E9MTFRtba3TYxobG52Wb2xstP+8e19PZVzh10EiNDRUI0eONHRsXFxcv/oPrhvX3b9w3f0L131jZk1pXCsqKkpRUVGm1xMoWGwJAICfGzJkiMLCwtTU1OSwv6mpSUlJSU6PSUpK6rV89/+6c05nCBIAAPi5iIgIZWZmqrKy0r7ParWqsrJS06dPd3rM9OnTHcpL0tGjR+3l09PTlZSU5FCmra1Nb731Vo/ndMavpzaMiIyMVElJSb97iyjXzXX3B1w3192fFRYWaunSpcrKytK0adNUXl6u9vZ25eXlSZKWLFmiESNGqLS0VJK0atUqzZo1S48//rjmzp2rAwcO6J133tGePXskSSEhIVq9erUeffRRjR07Vunp6frJT36i5ORkzZs3z+V2+fXtnwAA4As7duzQ1q1b1djYqIyMDD355JPKzs6WJM2ePVtpaWl69tln7eVfeOEFPfLIIzp//rzGjh2rLVu26N/+7d/sP7fZbCopKdGePXv0z3/+U7fffrt+8Ytf6Ktf/arLbSJIAAAAw1gjAQAADCNIAAAAwwgSAADAMIIEAAAwLOiDxO9+9ztlZ2crOjpaCQkJbt3SEugsFosyMjIUEhKi06dP+7o5pjp//rzuv/9+paenKzo6WmPGjFFJSYlHHmPrb9x9jXCgKy0t1dSpUxUbG6thw4Zp3rx5Onv2rK+b5XWbNm2y364X7BoaGvTd735XgwcPVnR0tCZOnKh33nnH181CD4I6SPzmN7/R4sWLlZeXp//93//V//zP/+jf//3ffd0sr/nRj35k6jPn/Ultba2sVqueeuopvffee/r5z3+u3bt36+GHH/Z10zzK3dcIB4M33nhD+fn5OnnypI4eParOzk7NmTNH7e3tvm6a17z99tt66qmnNGnSJF83xXT/+Mc/NHPmTA0YMECvvPKK3n//fT3++ONKSEjwddPQE5df7xVgOjs7bSNGjLA9/fTTvm6KT7z88su2cePG2d577z2nb3frD7Zs2WJLT0/3dTM8atq0abb8/Hz7566uLltycrKttLTUh63yrubmZpsk2xtvvOHrpnjFpUuXbGPHjrUdPXrUNmvWLNuqVat83SRTrVu3znb77bf7uhlwQ9COSNTU1KihoUGhoaGaMmWKhg8frm9961s6c+aMr5tmuqamJi1fvly/+tWvNHDgQF83x2daW1t10003+boZHtPR0aHq6mrl5OTY94WGhionJ0dVVVU+bJl3tba2SlJQ/dv2Jj8/X3PnznX4dw9mhw8fVlZWlubPn69hw4ZpypQp2rt3r6+bhV4EbZD46KOPJEkbNmzQI488oiNHjighIUGzZ8/WJ5984uPWmcdms2nZsmVasWKFsrKyfN0cnzl37py2b9+u733ve75uisf09hphd175G8isVqtWr16tmTNnasKECb5ujukOHDigmpoa+yOP+4OPPvpIu3bt0tixY/Xqq6/q+9//vlauXKnnnnvO101DDwIuSKxfv14hISG9bt3z5ZL04x//WPfcc48yMzO1b98+hYSE6IUXXvDxVbjP1evevn27Ll26pKKiIl832SNcve5rNTQ06K677tL8+fO1fPlyH7UcZsjPz9eZM2d04MABXzfFdPX19Vq1apWef/75fvXKaqvVqttuu02PPfaYpkyZogceeEDLly/X7t27fd009CDgXtq1Zs0aLVu2rNcyo0eP1t///ndJ0vjx4+37IyMjNXr0aNXV1ZnZRFO4et3Hjh1TVVXVdS+5ycrK0qJFiwIu1bt63d0uXLigO++8UzNmzLC/mCZYGHmNcDApKCjQkSNHdOLECY0cOdLXzTFddXW1mpubddttt9n3dXV16cSJE9qxY4csFovCwsJ82EJzDB8+3OHvtiTdcsst+s1vfuOjFuFGAi5IDB06VEOHDr1huczMTEVGRurs2bO6/fbbJUmdnZ06f/68UlNTzW6mx7l63U8++aQeffRR++cLFy4oNzdXBw8etL/YJZC4et3S1ZGIO++80z76FBoacANuvbr2NcLdtzF3v0a4oKDAt40zkc1m04MPPqhDhw7p+PHjSk9P93WTvOIb3/iG/vSnPznsy8vL07hx47Ru3bqgDBGSNHPmzOtu7/3ggw8C8u92fxFwQcJVcXFxWrFihUpKSpSSkqLU1FRt3bpVkjR//nwft848o0aNcvgcExMjSRozZkxQf4traGjQ7NmzlZqaqrKyMrW0tNh/Fkzf1m/0GuFglJ+fr/379+ull15SbGysfT1IfHy8oqOjfdw688TGxl63DmTQoEEaPHhwUK8PeeihhzRjxgw99thj+s53vqNTp05pz549QTfCGEyCNkhI0tatWxUeHq7Fixfrs88+U3Z2to4dO8b9yEHo6NGjOnfunM6dO3ddYLIF0QtuFyxYoJaWFhUXF9tfI1xRUXHdAsxgsmvXLklXX5F8rX379t1w2guBZ+rUqTp06JCKior005/+VOnp6SovL9eiRYt83TT0gNeIAwAAw4JrEhkAAHgVQQIAABhGkAAAAIYRJAAAgGEECQAAYBhBAgAAGEaQAAAAhhEkAACAYQQJAABgGEECAAAYRpAAAACG/f+VRP0FWrdjQQAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "nv = 2048\n", - "vmax = 6.4\n", - "dv = 2*vmax/nv\n", - "\n", - "v = np.linspace(-vmax+dv/2., vmax-dv/2., nv)\n", - "plt.contourf(v, v, (get_analytical_2d(0.001, 1000, v)))\n", - "plt.colorbar()" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "73bbf45c-a956-4142-986f-05dbfbf675ed", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "linear_solve_x = vmap(partial(lx.linear_solve, solver=lx.Tridiagonal()), in_axes=(None, 1))\n", - "linear_solve_y = vmap(partial(lx.linear_solve, solver=lx.Tridiagonal()), in_axes=(None, 0))\n", - "\n", - "@jit\n", - "def solve_diff_2d(dt, finp, diff_coeff):\n", - " coeff = -0.5*dt * diff_coeff / dv**2.\n", - " diag = 1-jnp.concatenate([jnp.ones([1]), 2*jnp.ones_like(v[1:-1]), jnp.ones([1])])*coeff\n", - " lower_diag = np.ones_like(v[1:])*coeff\n", - " upper_diag = np.ones_like(v[1:])*coeff\n", - " operator = lx.TridiagonalLinearOperator(diag, lower_diag, upper_diag)\n", - " \n", - " interm = finp + coeff*jnp.gradient(jnp.gradient(finp, axis=1), axis=1)\n", - " interm = linear_solve_x(operator, interm).value\n", - " interm = interm + coeff*jnp.gradient(jnp.gradient(interm, axis=0), axis=0)\n", - " \n", - " out = linear_solve_y(operator, interm).value\n", - " \n", - " return out\n", - "\n", - "class VectorField(eqx.Module):\n", - " \"\"\"\n", - " This function returns the function that defines $d_state / dt$\n", - "\n", - " All the pushers are chosen and initialized here and a single time-step is defined here.\n", - "\n", - " We use the time-integrators provided by diffrax, and therefore, only need $d_state / dt$ here\n", - "\n", - " :param cfg:\n", - " :return:\n", - " \"\"\"\n", - " v: jnp.ndarray\n", - " dt: float\n", - " kappa: float\n", - " \n", - " def __init__(self, v: jnp.ndarray, dt: float, kappa: float):\n", - " super().__init__()\n", - " self.v = v\n", - " self.dt = dt\n", - " self.kappa = kappa\n", - "\n", - " def __call__(self, t: float, y: jnp.ndarray, args):\n", - " return solve_diff_2d(self.dt, y, self.kappa)" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "9abfef74-d831-4dc7-8c2a-eb4109d83480", - "metadata": {}, - "outputs": [], - "source": [ - "tmax = 1800\n", - "dt = 0.1\n", - "kappa = 0.001\n", - "t0 = 1000\n", - "nt = int((tmax-t0)/dt + 1)\n", - "val0 = get_analytical_2d(kappa, t0, v)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "95cb4e5c-bc9f-4b9c-bed4-e3e896f9544a", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 100/100 [00:40<00:00, 2.49it/s]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "40.129 s\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "_t0_ = time()\n", - "val = np.copy(val0)\n", - "for i in tqdm(range(nt), total=nt):\n", - " val = solve_diff_2d(dt, val, kappa)\n", - "print(f\"{round(time() - _t0_, 3)} s\")" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "f585a881-25db-4597-b9a4-57ce9d27405c", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[32], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m _t0_ \u001b[38;5;241m=\u001b[39m time()\n\u001b[0;32m----> 2\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mdiffrax\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdiffeqsolve\u001b[49m\u001b[43m(\u001b[49m\u001b[43mterms\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdiffrax\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mODETerm\u001b[49m\u001b[43m(\u001b[49m\u001b[43mVectorField\u001b[49m\u001b[43m(\u001b[49m\u001b[43mv\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdt\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdiffusion_coefficient\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msolver\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mStepper\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_steps\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m1e9\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mt0\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mt0\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mt1\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtmax\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdt0\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdt\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my0\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mjnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marray\u001b[49m\u001b[43m(\u001b[49m\u001b[43mval0\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msaveat\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdiffrax\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mSaveAt\u001b[49m\u001b[43m(\u001b[49m\u001b[43mts\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlinspace\u001b[49m\u001b[43m(\u001b[49m\u001b[43mt0\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtmax\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m101\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mround\u001b[39m(time()\u001b[38;5;250m \u001b[39m\u001b[38;5;241m-\u001b[39m\u001b[38;5;250m \u001b[39m_t0_,\u001b[38;5;250m \u001b[39m\u001b[38;5;241m3\u001b[39m)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m s\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", - " \u001b[0;31m[... skipping hidden 4 frame]\u001b[0m\n", - "File \u001b[0;32m~/.conda/envs/adept/lib/python3.10/site-packages/jax/_src/pjit.py:256\u001b[0m, in \u001b[0;36m_cpp_pjit..cache_miss\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 254\u001b[0m \u001b[38;5;129m@api_boundary\u001b[39m\n\u001b[1;32m 255\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcache_miss\u001b[39m(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m--> 256\u001b[0m outs, out_flat, out_tree, args_flat, jaxpr \u001b[38;5;241m=\u001b[39m \u001b[43m_python_pjit_helper\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 257\u001b[0m \u001b[43m \u001b[49m\u001b[43mfun\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minfer_params_fn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 258\u001b[0m executable \u001b[38;5;241m=\u001b[39m _read_most_recent_pjit_call_executable(jaxpr)\n\u001b[1;32m 259\u001b[0m fastpath_data \u001b[38;5;241m=\u001b[39m _get_fastpath_data(executable, out_tree, args_flat, out_flat)\n", - "File \u001b[0;32m~/.conda/envs/adept/lib/python3.10/site-packages/jax/_src/pjit.py:167\u001b[0m, in \u001b[0;36m_python_pjit_helper\u001b[0;34m(fun, infer_params_fn, *args, **kwargs)\u001b[0m\n\u001b[1;32m 165\u001b[0m dispatch\u001b[38;5;241m.\u001b[39mcheck_arg(arg)\n\u001b[1;32m 166\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 167\u001b[0m out_flat \u001b[38;5;241m=\u001b[39m \u001b[43mpjit_p\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbind\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs_flat\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mparams\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 168\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m pxla\u001b[38;5;241m.\u001b[39mDeviceAssignmentMismatchError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 169\u001b[0m fails, \u001b[38;5;241m=\u001b[39m e\u001b[38;5;241m.\u001b[39margs\n", - "File \u001b[0;32m~/.conda/envs/adept/lib/python3.10/site-packages/jax/_src/core.py:2656\u001b[0m, in \u001b[0;36mAxisPrimitive.bind\u001b[0;34m(self, *args, **params)\u001b[0m\n\u001b[1;32m 2652\u001b[0m axis_main \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mmax\u001b[39m((axis_frame(a)\u001b[38;5;241m.\u001b[39mmain_trace \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m used_axis_names(\u001b[38;5;28mself\u001b[39m, params)),\n\u001b[1;32m 2653\u001b[0m default\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, key\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mlambda\u001b[39;00m t: \u001b[38;5;28mgetattr\u001b[39m(t, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlevel\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m))\n\u001b[1;32m 2654\u001b[0m top_trace \u001b[38;5;241m=\u001b[39m (top_trace \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m axis_main \u001b[38;5;129;01mor\u001b[39;00m axis_main\u001b[38;5;241m.\u001b[39mlevel \u001b[38;5;241m<\u001b[39m top_trace\u001b[38;5;241m.\u001b[39mlevel\n\u001b[1;32m 2655\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m axis_main\u001b[38;5;241m.\u001b[39mwith_cur_sublevel())\n\u001b[0;32m-> 2656\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbind_with_trace\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtop_trace\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparams\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/.conda/envs/adept/lib/python3.10/site-packages/jax/_src/core.py:388\u001b[0m, in \u001b[0;36mPrimitive.bind_with_trace\u001b[0;34m(self, trace, args, params)\u001b[0m\n\u001b[1;32m 387\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mbind_with_trace\u001b[39m(\u001b[38;5;28mself\u001b[39m, trace, args, params):\n\u001b[0;32m--> 388\u001b[0m out \u001b[38;5;241m=\u001b[39m \u001b[43mtrace\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mprocess_primitive\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mmap\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mtrace\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfull_raise\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparams\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 389\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mmap\u001b[39m(full_lower, out) \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmultiple_results \u001b[38;5;28;01melse\u001b[39;00m full_lower(out)\n", - "File \u001b[0;32m~/.conda/envs/adept/lib/python3.10/site-packages/jax/_src/core.py:868\u001b[0m, in \u001b[0;36mEvalTrace.process_primitive\u001b[0;34m(self, primitive, tracers, params)\u001b[0m\n\u001b[1;32m 867\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mprocess_primitive\u001b[39m(\u001b[38;5;28mself\u001b[39m, primitive, tracers, params):\n\u001b[0;32m--> 868\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mprimitive\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mimpl\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mtracers\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mparams\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/.conda/envs/adept/lib/python3.10/site-packages/jax/_src/pjit.py:1212\u001b[0m, in \u001b[0;36m_pjit_call_impl\u001b[0;34m(jaxpr, in_shardings, out_shardings, resource_env, donated_invars, name, keep_unused, inline, *args)\u001b[0m\n\u001b[1;32m 1209\u001b[0m donated_argnums \u001b[38;5;241m=\u001b[39m [i \u001b[38;5;28;01mfor\u001b[39;00m i, d \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(donated_invars) \u001b[38;5;28;01mif\u001b[39;00m d]\n\u001b[1;32m 1210\u001b[0m has_explicit_sharding \u001b[38;5;241m=\u001b[39m _pjit_explicit_sharding(\n\u001b[1;32m 1211\u001b[0m in_shardings, out_shardings, \u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[0;32m-> 1212\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mxc\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_xla\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpjit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcall_impl_cache_miss\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdonated_argnums\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1213\u001b[0m \u001b[43m \u001b[49m\u001b[43mtree_util\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdispatch_registry\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1214\u001b[0m \u001b[43m \u001b[49m\u001b[43m_get_cpp_global_cache\u001b[49m\u001b[43m(\u001b[49m\u001b[43mhas_explicit_sharding\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/.conda/envs/adept/lib/python3.10/site-packages/jax/_src/pjit.py:1196\u001b[0m, in \u001b[0;36m_pjit_call_impl..call_impl_cache_miss\u001b[0;34m(*args_, **kwargs_)\u001b[0m\n\u001b[1;32m 1195\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall_impl_cache_miss\u001b[39m(\u001b[38;5;241m*\u001b[39margs_, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs_):\n\u001b[0;32m-> 1196\u001b[0m out_flat, compiled \u001b[38;5;241m=\u001b[39m \u001b[43m_pjit_call_impl_python\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1197\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mjaxpr\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mjaxpr\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43min_shardings\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43min_shardings\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1198\u001b[0m \u001b[43m \u001b[49m\u001b[43mout_shardings\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mout_shardings\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mresource_env\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mresource_env\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1199\u001b[0m \u001b[43m \u001b[49m\u001b[43mdonated_invars\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdonated_invars\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkeep_unused\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mkeep_unused\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1200\u001b[0m \u001b[43m \u001b[49m\u001b[43minline\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minline\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1201\u001b[0m fastpath_data \u001b[38;5;241m=\u001b[39m _get_fastpath_data(\n\u001b[1;32m 1202\u001b[0m compiled, tree_structure(out_flat), args, out_flat)\n\u001b[1;32m 1203\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m out_flat, fastpath_data\n", - "File \u001b[0;32m~/.conda/envs/adept/lib/python3.10/site-packages/jax/_src/pjit.py:1152\u001b[0m, in \u001b[0;36m_pjit_call_impl_python\u001b[0;34m(jaxpr, in_shardings, out_shardings, resource_env, donated_invars, name, keep_unused, inline, *args)\u001b[0m\n\u001b[1;32m 1146\u001b[0m distributed_debug_log((\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRunning pjit\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124md function\u001b[39m\u001b[38;5;124m\"\u001b[39m, name),\n\u001b[1;32m 1147\u001b[0m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124min_shardings\u001b[39m\u001b[38;5;124m\"\u001b[39m, in_shardings),\n\u001b[1;32m 1148\u001b[0m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mout_shardings\u001b[39m\u001b[38;5;124m\"\u001b[39m, out_shardings),\n\u001b[1;32m 1149\u001b[0m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mabstract args\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28mmap\u001b[39m(xla\u001b[38;5;241m.\u001b[39mabstractify, args)),\n\u001b[1;32m 1150\u001b[0m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfingerprint\u001b[39m\u001b[38;5;124m\"\u001b[39m, fingerprint))\n\u001b[1;32m 1151\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 1152\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcompiled\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43munsafe_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m, compiled\n\u001b[1;32m 1153\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mFloatingPointError\u001b[39;00m:\n\u001b[1;32m 1154\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m config\u001b[38;5;241m.\u001b[39mdebug_nans\u001b[38;5;241m.\u001b[39mvalue \u001b[38;5;129;01mor\u001b[39;00m config\u001b[38;5;241m.\u001b[39mdebug_infs\u001b[38;5;241m.\u001b[39mvalue \u001b[38;5;66;03m# compiled_fun can only raise in this case\u001b[39;00m\n", - "File \u001b[0;32m~/.conda/envs/adept/lib/python3.10/site-packages/jax/_src/profiler.py:340\u001b[0m, in \u001b[0;36mannotate_function..wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 337\u001b[0m \u001b[38;5;129m@wraps\u001b[39m(func)\n\u001b[1;32m 338\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mwrapper\u001b[39m(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 339\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m TraceAnnotation(name, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mdecorator_kwargs):\n\u001b[0;32m--> 340\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 341\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m wrapper\n", - "File \u001b[0;32m~/.conda/envs/adept/lib/python3.10/site-packages/jax/_src/interpreters/pxla.py:1144\u001b[0m, in \u001b[0;36mExecuteReplicated.__call__\u001b[0;34m(self, *args)\u001b[0m\n\u001b[1;32m 1141\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mordered_effects \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhas_unordered_effects\n\u001b[1;32m 1142\u001b[0m \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhas_host_callbacks):\n\u001b[1;32m 1143\u001b[0m input_bufs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_add_tokens_to_inputs(input_bufs)\n\u001b[0;32m-> 1144\u001b[0m results \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mxla_executable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute_sharded\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1145\u001b[0m \u001b[43m \u001b[49m\u001b[43minput_bufs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mwith_tokens\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\n\u001b[1;32m 1146\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1147\u001b[0m result_token_bufs \u001b[38;5;241m=\u001b[39m results\u001b[38;5;241m.\u001b[39mdisassemble_prefix_into_single_device_arrays(\n\u001b[1;32m 1148\u001b[0m \u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mordered_effects))\n\u001b[1;32m 1149\u001b[0m sharded_runtime_token \u001b[38;5;241m=\u001b[39m results\u001b[38;5;241m.\u001b[39mconsume_token()\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - } - ], - "source": [ - "_t0_ = time()\n", - "result = diffrax.diffeqsolve(terms=diffrax.ODETerm(VectorField(v, dt, kappa)), solver=Stepper(), max_steps=int(1e9), t0=t0, t1=tmax, dt0=dt, y0=jnp.array(val0), saveat=diffrax.SaveAt(ts=np.linspace(t0, tmax, 101)))\n", - "print(f\"{round(time() - _t0_, 3)} s\")" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "31ac49bc-e4cb-4171-bae3-3cfc65a1a3e3", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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5eXlnps7a2trFRv71UX8adOmaevWrbr33nt1zz336IILLtAzzzyjCRMmeNrcfffdam1t1e23365PP/1UX//611VeXm7LdAj4x83/rXBskYljQxcn55Kj38MDAAAAAKHgHh4AAAAArkXBAwAAAMC1KHgAAAAAuBYFDwAAAADXouA5TWZmpmJiYrw+a9as6XGdL7/8UgsXLtTgwYPVv39/XXvttWe9RCncDh8+rNtuu02jR49Wv379NHbsWBUXF/f65t0ZM2ac9fdYsGCBTb3u3vr165WZmanExETl5ORo7969PbZ/+umnNW7cOCUmJuqSSy7Rc889Z1NP/VdSUqIpU6ZowIABGjZsmGbPnq2DBw/2uM4TTzxx1vfjxKdprVq16qx+jhs3rsd1IuE7A+zg1lySyKZIGOfIJm+R8J3BNwqeM9x333365JNPPJ9Fixb12P773/++/vCHP+jpp5/WK6+8oiNHjui///u/beqtfw4cOKDOzk794he/0Ntvv62f/exn2rhxo+65555e150/f77X3+PBBx+0ocfd2759u4qKilRcXKyamhpNnDhR+fn5ampq8tl+9+7duummm3TbbbfpzTff1OzZszV79mzt37/f5p737JVXXtHChQu1Z88e7dq1SydOnNDMmTPV2tra43pJSUle389HH31kU48Dc/HFF3v18y9/+Uu3bSPlOwPs4sZcksimSBjnyKavRMp3hm4Y8MjIyDB+9rOf+d3+008/Nfr27Ws8/fTTnmXvvvuuIcmoqqqyoIfmefDBB43Ro0f32Gb69OnGXXfdZU+H/DR16lRj4cKFnp87OjqMtLQ0o6SkxGf7G264wZg1a5bXspycHOO73/2upf0MVVNTkyHJeOWVV7pts2XLFiM5Odm+TgWpuLjYmDhxot/tI/U7A6wQTblkGGST08c5sinyvjOcwhWeM6xZs0aDBw/WpEmT9NBDD+nkyZPdtq2urtaJEyeUl5fnWTZu3DiNGjVKVVVVdnQ3aM3NzRo0aFCv7Z566ikNGTJEEyZM0IoVK3T8+HEbeudbe3u7qqurvf7esbGxysvL6/bvXVVV5dVekvLz8yPi+5HU63f0+eefKyMjQ+np6frP//xPvf3223Z0L2Dvv/++0tLSNGbMGN18882qra3ttm2kfmeAVaIllySyyenfEdkUed8ZTokLdwec5M4779Rl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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(1, 2, figsize=(10, 4))\n", - "\n", - "cb = ax[0].contourf(v, v, val0)\n", - "plt.colorbar(cb)\n", - "\n", - "cb = ax[1].contourf(v, v, val)\n", - "plt.colorbar(cb)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "8f93c2e2-13f9-4a2c-b90e-659a8aa34e9b", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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qHnz5jndLp++/RMAAPzTrl27tH37djU0NCgtLU1PPPGEMjMzJUmzZ89WSkqKnnnmGXv5559/Xo888oguXLigMWPGaNu2bfr3f/93+89tNpuKioq0b98+/f3vf9edd96pn//85/qXf/kXp9tEkAAAAIaxRgIAABhGkAAAAIYRJAAAgGEECQAAYFjAB4nf/va3yszMVGRkpOLi4ly6pcXfWSwWpaWlKSgoSGfOnPF2c0x14cIFPfDAA0pNTVVkZKRGjx6toqIitzzG1te4+hphf1dcXKypU6cqOjpaw4YN07x583Tu3DlvN8vjtmzZYr9dL9DV19fr29/+tgYPHqzIyEhNmDBBb7/9trebhR4EdJD49a9/rcWLFysnJ0f/93//p//93//Vf/zHf3i7WR7zwx/+0NRnzvuSmpoaWa1WPfnkk3r33Xf1s5/9THv37tXDDz/s7aa5lauvEQ4Er7/+unJzc3Xq1CkdP35cHR0dmjNnjtra2rzdNI9566239OSTT2rixIneborp/va3v2nmzJkaMGCAXn75Zb333nt67LHHFBcX5+2moSdOv97Lz3R0dNhGjBhhe+qpp7zdFK946aWXbGPHjrW9++673b7drT/Ytm2bLTU11dvNcKtp06bZcnNz7Z87OzttiYmJtuLiYi+2yrOamppskmyvv/66t5viEZcvX7aNGTPGdvz4cdusWbNsq1ev9naTTLV+/XrbnXfe6e1mwAUBOyJRXV2t+vp6BQcHa/LkyRo+fLi+/vWv6+zZs95umukaGxu1fPly/fKXv9TAgQO93RyvaWlp0S233OLtZrhNe3u7qqqqlJWVZd8XHBysrKwsVVZWerFlntXS0iJJAfVv25vc3FzNnTvX4d89kB09elQZGRmaP3++hg0bpsmTJ2v//v3ebhZ6EbBB4sMPP5Qkbdy4UY888oiOHTumuLg4zZ49W5988omXW2cem82mZcuWacWKFcrIyPB2c7zm/Pnz2rlzp7773e96uylu09trhF155a8/s1qtWrNmjWbOnKnx48d7uzmmO3TokKqrq+2PPO4PPvzwQ+3Zs0djxozRK6+8ooceekirVq3Ss88+6+2moQd+FyQ2bNigoKCgXreu+XJJ+tGPfqR7771X6enpOnDggIKCgvT88897+Spc5+x179y5U5cvX1ZBQYG3m+wWzl73terr63XPPfdo/vz5Wr58uZdaDjPk5ubq7NmzOnTokLebYrq6ujqtXr1azz33XL96ZbXVatWUKVO0efNmTZ48WQ8++KCWL1+uvXv3ertp6IHfvbRr7dq1WrZsWa9lRo0apb/+9a+SpHHjxtn3h4eHa9SoUaqtrTWziaZw9rpPnDihysrKG15yk5GRoUWLFvldqnf2urtcvHhRd999t2bMmGF/MU2gMPIa4UCSl5enY8eO6eTJkxo5cqS3m2O6qqoqNTU1acqUKfZ9nZ2dOnnypHbt2iWLxaKQkBAvttAcw4cPd/i7LUm33367fv3rX3upRbgZvwsSQ4cO1dChQ29aLj09XeHh4Tp37pzuvPNOSVJHR4cuXLig5ORks5vpds5e9xNPPKFHH33U/vnixYvKzs7W4cOH7S928SfOXrf0xUjE3XffbR99Cg72uwG3Xl37GuGu25i7XiOcl5fn3caZyGazaeXKlTpy5IgqKiqUmprq7SZ5xFe/+lX98Y9/dNiXk5OjsWPHav369QEZIiRp5syZN9ze+/777/vl3+3+wu+ChLNiYmK0YsUKFRUVKSkpScnJydq+fbskaf78+V5unXluvfVWh89RUVGSpNGjRwf0t7j6+nrNnj1bycnJKikpUXNzs/1ngfRt/WavEQ5Eubm5OnjwoF588UVFR0fb14PExsYqMjLSy60zT3R09A3rQAYNGqTBgwcH9PqQ73//+5oxY4Y2b96sb33rWzp9+rT27dsXcCOMgSRgg4Qkbd++XaGhoVq8eLE+++wzZWZm6sSJE9yPHICOHz+u8+fP6/z58zcEJlsAveB2wYIFam5uVmFhof01wmVlZTcswAwke/bskfTFK5KvdeDAgZtOe8H/TJ06VUeOHFFBQYF+8pOfKDU1VaWlpVq0aJG3m4Ye8BpxAABgWGBNIgMAAI8iSAAAAMMIEgAAwDCCBAAAMIwgAQAADCNIAAAAwwgSAADAMIIEAAAwjCABAAAMI0gAAADDCBIAAMCw/w9nKjZsMpogHgAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.contourf(v, v, (get_analytical_2d(0.001, t_start+nt*dt, v)))\n", - "plt.colorbar()" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "28be87e2-02a5-494f-9bc7-befa77a32f02", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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9OiBoqIizJw5EwBQUVGByspKaLVacb9r165FTU2NOCxVWFgIlUolhhGtVovDhw+b7LuwsFDcBwBMnDgRFRUVJmW++uorhIWFmfM2iDhhl4iIyElERUVhxowZSE1NxalTp/Dpp58iIyMDc+bMEa80unr1KoYNGyb2pPj5+SElJQWZmZn4+OOPUVpaiuTkZGi1WowfPx4AMH36dAwfPhxPPPEEvvjiCxw9ehSrVq1Cenq6ONS1cOFCXLp0CcuWLUN5eTlee+01/PWvf8WSJUvE+i1ZsgSfffYZ1q1bh4sXL2Lv3r3YsWMH0tPTLTpPhhciIiInsmfPHgwbNgzTpk3DI488gkmTJmHHjh3i+ubmZlRUVOBf//qXuOzll1/Go48+ipkzZ+LBBx+EWq3G3/72N3G9h4cH8vPz4eHhAa1Wi8cffxzz5s3DCy+8IJYJDw/HoUOHUFhYiFGjRmHTpk148803ER8fL5YZO3Ys3n//fbzzzjsYMWIEXnzxRWzevBlJSUkWnSPv80JERE7Bnvd5iQt80qqrjVqMTfivmjclraszY88LERERKQrDCxERESkKwwsREREpCsMLERERKQrDCxERESkKwwsREREpCsMLERERKQrDCxERESkKwwsREREpCsMLERERKQrDCxERESkKwwsREREpCsMLERERKQrDCxERESkKwwsREREpCsMLERERKQrDCxERESkKwwsREREpCsMLERERKQrDCxERESkKwwsREREpCsMLERERKQrDCxERESkKwwsREREpiqTh5dChQ9BoNPD19UXfvn2RmJgo5eGIiIjIBXhKteP33nsPqampWLduHR566CG0tLSgrKxMqsMRERGRi5AkvLS0tGDRokXYsGEDUlJSxOXDhw+X4nBERETkQiQZNjp79iyuXr0Kd3d3jB49GsHBwXj44Ye77HlpbGyEwWAweRERERHdSZLwcunSJQDA6tWrsWrVKuTn56Nv376YMmUKamtrO9wuNzcXfn5+4is0NFSK6hEREZGCWRReVqxYATc3t05f5eXlMBqNAIDnnnsOM2fORExMDHbu3Ak3NzccOHCgw/1nZWVBr9eLr6qqKuvOjoiIiJyORXNeli5digULFnRaJiIiAt9//z0A0zku3t7eiIiIQGVlZYfbent7w9vb25IqERERkYuxKLwEBAQgICCgy3IxMTHw9vZG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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "error = val - get_analytical_2d(0.001, t_start+nt*dt, v)\n", - "plt.contourf(v, v, error)\n", - "plt.colorbar()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "5f548409-f222-4b83-9493-f9f2b681c2c7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(v, error[1024])" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "28074d9e-6bd1-45cf-8aa2-f4d49a99e404", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(v, np.log10(np.abs(error[1024]/val[1024])))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c7782555-5766-4d10-8a14-b6376149d2d4", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1f303d6a-a072-49aa-91e1-efbb58798564", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "db82b134-6680-41b0-9aa7-aba1eb70d3a5", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9eb3da7b-5e83-42d2-815b-747086ad4dd4", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "542bd93d-dcf2-4dc1-a7dd-a7dbd579a93a", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "adept-cpu", - "language": "python", - "name": "adept-cpu" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/adept/vlasov1d2v/helpers.py b/adept/vlasov1d2v/helpers.py index ff6a00c..5e2d230 100644 --- a/adept/vlasov1d2v/helpers.py +++ b/adept/vlasov1d2v/helpers.py @@ -1,6 +1,6 @@ # Copyright (c) Ergodic LLC 2023 # research@ergodic.io -from typing import Dict +from typing import Dict, Tuple import os from time import time @@ -9,8 +9,9 @@ import numpy as np import xarray, mlflow, pint from jax import numpy as jnp -from diffrax import ODETerm, SubSaveAt +from diffrax import ODETerm, SubSaveAt, diffeqsolve, SaveAt from matplotlib import pyplot as plt +from equinox import filter_jit from adept.vlasov1d2v.integrator import VlasovMaxwell, Stepper from adept.vlasov1d2v.storage import store_f, store_fields, get_save_quantities @@ -289,7 +290,33 @@ def get_solver_quantities(cfg: Dict) -> Dict: return cfg_grid -def init_state(cfg: Dict, td) -> Dict: +def get_run_fn(cfg): + diffeqsolve_quants = get_diffeqsolve_quants(cfg) + + @filter_jit + def _run_(_models_, _state_, _args_, time_quantities: Dict): + + _state_, _args_ = apply_models(_models_, _state_, _args_, cfg) + # if "terms" in cfg.keys(): + # args["terms"] = cfg["terms"] + solver_result = diffeqsolve( + terms=diffeqsolve_quants["terms"], + solver=diffeqsolve_quants["solver"], + t0=time_quantities["t0"], + t1=time_quantities["t1"], + max_steps=cfg["grid"]["max_steps"], + dt0=cfg["grid"]["dt"], + y0=_state_, + args=_args_, + saveat=SaveAt(**diffeqsolve_quants["saveat"]), + ) + + return solver_result, _state_, _args_ + + return _run_ + + +def init_state(cfg: Dict, td) -> Tuple[Dict, Dict]: """ This function initializes the state @@ -308,7 +335,7 @@ def init_state(cfg: Dict, td) -> Dict: for field in ["a", "da", "prev_a"]: state[field] = jnp.zeros(cfg["grid"]["nx"] + 2) # need boundary cells - return state + return state, {"drivers": cfg["drivers"]} def get_diffeqsolve_quants(cfg): @@ -376,3 +403,7 @@ def post_process(result, cfg: Dict, td: str): mlflow.log_metrics({"postprocess_time_min": round((time() - t0) / 60, 3)}) return {"fields": fields_xr, "dists": f_xr, "scalars": scalars_xr} + + +def apply_models(models, state, args, cfg): + return state, args diff --git a/adept/vlasov1d2v/integrator.py b/adept/vlasov1d2v/integrator.py index dc9e566..94905bc 100644 --- a/adept/vlasov1d2v/integrator.py +++ b/adept/vlasov1d2v/integrator.py @@ -191,7 +191,7 @@ def __init__(self, cfg): self.ex_driver = field.Driver(cfg["grid"]["x"], driver_key="ex") def compute_charges(self, f): - return jnp.trapz(jnp.trapz(f, dx=self.cfg["grid"]["dv"], axis=2), dx=self.cfg["grid"]["dv"], axis=1) + return jnp.sum(jnp.sum(f, axis=2), axis=1) * self.cfg["grid"]["dv"] * self.cfg["grid"]["dv"] def nu_prof(self, t, nu_args): t_L = nu_args["time"]["center"] - nu_args["time"]["width"] * 0.5 diff --git a/adept/vlasov1d2v/pushers/field.py b/adept/vlasov1d2v/pushers/field.py index 66514b5..a366ec9 100644 --- a/adept/vlasov1d2v/pushers/field.py +++ b/adept/vlasov1d2v/pushers/field.py @@ -112,7 +112,7 @@ def __init__(self, ion_charge, one_over_kx, dv): self.dv = dv def compute_charges(self, f): - return jnp.trapz(jnp.trapz(f, dx=self.dv, axis=2), dx=self.dv, axis=1) + return jnp.sum(jnp.sum(f, axis=2), axis=1) * self.dv * self.dv def __call__(self, f: jnp.ndarray, prev_ex: jnp.ndarray, dt: jnp.float64): return jnp.real(jnp.fft.ifft(1j * self.one_over_kx * jnp.fft.fft(self.ion_charge - self.compute_charges(f)))) @@ -122,7 +122,10 @@ class AmpereSolver: def __init__(self, cfg): super(AmpereSolver, self).__init__() self.vx = cfg["grid"]["v"] - self.vx_moment = partial(jnp.trapz, dx=cfg["grid"]["dv"], axis=1) + self.dv = cfg["grid"]["dv"] + + def vx_moment(self, f): + return jnp.sum(f, axis=1) * self.dv def __call__(self, f: jnp.ndarray, prev_ex: jnp.ndarray, dt: jnp.float64): return prev_ex - dt * self.vx_moment(self.vx[None, :] * f) @@ -138,8 +141,8 @@ def __init__(self, cfg): def __call__(self, f: jnp.ndarray, prev_ex: jnp.ndarray, dt: jnp.float64): prev_ek = jnp.fft.fft(prev_ex, axis=0) fk = jnp.fft.fft(f, axis=0) - new_ek = prev_ek + self.one_over_ikx * jnp.trapz( - fk * (jnp.exp(-1j * self.kx * dt * self.vx) - 1), dx=self.dv, axis=1 + new_ek = ( + prev_ek + self.one_over_ikx * jnp.sum(fk * (jnp.exp(-1j * self.kx * dt * self.vx) - 1), axis=1) * self.dv ) return jnp.real(jnp.fft.ifft(new_ek)) diff --git a/adept/vlasov1d2v/pushers/fokker_planck.py b/adept/vlasov1d2v/pushers/fokker_planck.py index 005cbf3..f4f3ea8 100644 --- a/adept/vlasov1d2v/pushers/fokker_planck.py +++ b/adept/vlasov1d2v/pushers/fokker_planck.py @@ -57,7 +57,9 @@ def __init__(self, cfg): f_mx = np.exp(-self.cfg["grid"]["v"][None, :] ** 2.0 / 2.0) self.f_mx = f_mx / np.trapz(f_mx, dx=self.cfg["grid"]["dv"], axis=1)[:, None] self.dv = self.cfg["grid"]["dv"] - self.vx_moment = partial(jnp.trapz, axis=1, dx=self.dv) + + def vx_moment(self, f_xv): + return jnp.sum(f_xv, axis=1) * self.dv def __call__(self, nu_K, f_xv, dt) -> jnp.ndarray: nu_Kxdt = dt * nu_K[:, None] @@ -86,13 +88,13 @@ def ddy(self, f_vxvy: jnp.ndarray): return jnp.gradient(f_vxvy, self.dv, axis=1) def get_init_quants_x(self, f_vxvy: jnp.ndarray): - vxbar = jnp.trapz(jnp.trapz(f_vxvy * self.v[:, None], dx=self.dv, axis=1), dx=self.dv, axis=0) - v0t_sq = jnp.trapz(jnp.trapz(f_vxvy * (self.v[:, None] - vxbar) ** 2.0, dx=self.dv, axis=1), dx=self.dv, axis=0) + vxbar = jnp.sum(jnp.sum(f_vxvy * self.v[:, None], axis=1), axis=0) * self.dv * self.dv + v0t_sq = jnp.sum(jnp.sum(f_vxvy * (self.v[:, None] - vxbar) ** 2.0, axis=1), axis=0) * self.dv * self.dv return vxbar, v0t_sq def get_init_quants_y(self, f_vxvy: jnp.ndarray): - vybar = jnp.trapz(jnp.trapz(f_vxvy * self.v[None, :], dx=self.dv, axis=1), dx=self.dv, axis=0) - v0t_sq = jnp.trapz(jnp.trapz(f_vxvy * (self.v[None, :] - vybar) ** 2.0, dx=self.dv, axis=1), dx=self.dv, axis=0) + vybar = jnp.sum(jnp.sum(f_vxvy * self.v[None, :], axis=1), axis=0) * self.dv * self.dv + v0t_sq = jnp.sum(jnp.sum(f_vxvy * (self.v[None, :] - vybar) ** 2.0, axis=1), axis=0) * self.dv * self.dv return vybar, v0t_sq diff --git a/adept/vlasov1d2v/storage.py b/adept/vlasov1d2v/storage.py index 9c206f8..35a637d 100644 --- a/adept/vlasov1d2v/storage.py +++ b/adept/vlasov1d2v/storage.py @@ -128,7 +128,7 @@ def get_field_save_func(cfg, k): if {"t"} == set(cfg["save"][k].keys()): def _calc_moment_(inp): - return jnp.trapz(jnp.trapz(inp, dx=cfg["grid"]["dv"], axis=2), dx=cfg["grid"]["dv"], axis=1) + return jnp.sum(jnp.sum(inp, axis=2), axis=1) * cfg["grid"]["dv"] * cfg["grid"]["dv"] def fields_save_func(t, y, args): temp = { @@ -221,7 +221,7 @@ def interp_vx(fp): return fp def dist_save_func(t, y, args): - fxvx = jnp.trapz(y["electron"], dx=cfg["grid"]["dv"], axis=2) + fxvx = jnp.sum(y["electron"], axis=2) * cfg["grid"]["dv"] f_interp_x = interp_x(fp=fxvx) f_interp_xv = interp_vx(fp=f_interp_x) return f_interp_xv @@ -273,7 +273,7 @@ def get_default_save_func(cfg): dv = cfg["grid"]["dv"] def _calc_mean_moment_(inp): - return jnp.mean(jnp.trapz(jnp.trapz(inp, dx=dv, axis=2), dx=dv, axis=1)) + return jnp.mean(jnp.sum(jnp.sum(inp, axis=2), axis=1)) * dv * dv def save(t, y, args): scalars = { diff --git a/adept/vlasov2d/helpers.py b/adept/vlasov2d/helpers.py index 164ad7a..80ed8a6 100644 --- a/adept/vlasov2d/helpers.py +++ b/adept/vlasov2d/helpers.py @@ -1,6 +1,6 @@ # Copyright (c) Ergodic LLC 2023 # research@ergodic.io -from typing import Dict, List +from typing import Dict, List, Tuple import os from time import time @@ -8,8 +8,9 @@ import numpy as np import xarray, mlflow, pint, yaml from jax import numpy as jnp -from diffrax import ODETerm, SubSaveAt +from diffrax import ODETerm, SubSaveAt, diffeqsolve, SaveAt from matplotlib import pyplot as plt +from equinox import filter_jit from adept.vlasov2d.pushers import time as time_integrator from adept.vlasov2d.storage import store_f, store_fields, get_save_quantities @@ -317,7 +318,33 @@ def get_solver_quantities(cfg: Dict) -> Dict: return cfg_grid -def init_state(cfg: Dict, td) -> Dict: +def get_run_fn(cfg): + diffeqsolve_quants = get_diffeqsolve_quants(cfg) + + @filter_jit + def _run_(_models_, _state_, _args_, time_quantities: Dict): + + _state_, _args_ = apply_models(_models_, _state_, _args_, cfg) + # if "terms" in cfg.keys(): + # args["terms"] = cfg["terms"] + solver_result = diffeqsolve( + terms=diffeqsolve_quants["terms"], + solver=diffeqsolve_quants["solver"], + t0=time_quantities["t0"], + t1=time_quantities["t1"], + max_steps=cfg["grid"]["max_steps"], + dt0=cfg["grid"]["dt"], + y0=_state_, + args=_args_, + saveat=SaveAt(**diffeqsolve_quants["saveat"]), + ) + + return solver_result, _state_, _args_ + + return _run_ + + +def init_state(cfg: Dict, td) -> Tuple[Dict, Dict]: """ This function initializes the state @@ -337,7 +364,7 @@ def init_state(cfg: Dict, td) -> Dict: # for nm, quant in state.items(): # state[nm] = jnp.fft.fft2(quant, axes=(0, 1)).view(dtype=jnp.float64) - return state + return state, {"drivers": cfg["drivers"]} def get_diffeqsolve_quants(cfg): @@ -400,3 +427,7 @@ def post_process(result, cfg: Dict, td: str): mlflow.log_metrics({"postprocess_time_min": round((time() - t0) / 60, 3)}) return {"fields": fields_xr, "dists": f_xr} + + +def apply_models(models, state, args, cfg): + return state, args diff --git a/adept/vlasov2d/pushers/field.py b/adept/vlasov2d/pushers/field.py index c1e6551..e06a9d7 100644 --- a/adept/vlasov2d/pushers/field.py +++ b/adept/vlasov2d/pushers/field.py @@ -16,8 +16,6 @@ def __init__(self, cfg): self.kx_mask = jnp.where(jnp.abs(self.kx) > 0, 1, 0)[:, None] self.ky = cfg["grid"]["ky"][None, :] self.ky_mask = jnp.where(jnp.abs(self.ky) > 0, 1, 0)[None, :] - self.vx_mom = partial(jnp.trapz, dx=cfg["grid"]["dvx"], axis=2) - self.vy_mom = partial(jnp.trapz, dx=cfg["grid"]["dvy"], axis=3) self.dvx = cfg["grid"]["dvx"] self.dvy = cfg["grid"]["dvy"] self.vx = cfg["grid"]["vx"][None, None, :, None] @@ -27,11 +25,17 @@ def __init__(self, cfg): def compute_charge(self, f): return self.vx_mom(self.vy_mom(f)) + def vx_mom(self, f): + return jnp.sum(f, axis=2) * self.dvx + + def vy_mom(self, f): + return jnp.sum(f, axis=3) * self.dvy + def compute_jx(self, f): - return jnp.trapz(jnp.trapz(self.vx * f, dx=self.dvy, axis=3), dx=self.dvx, axis=2) * self.kx_mask + return jnp.sum(jnp.sum(self.vx * f, axis=3), axis=2) * self.kx_mask * self.dvx * self.dvy def compute_jy(self, f): - return jnp.trapz(jnp.trapz(self.vy * f, dx=self.dvy, axis=3), dx=self.dvx, axis=2) * self.ky_mask + return jnp.sum(jnp.sum(self.vy * f, axis=3), axis=2) * self.ky_mask * self.dvx * self.dvy def ampere(self, exk, eyk, bzk, dt): exkp = exk # - dt * (1j * self.ky * bzk) @@ -43,18 +47,22 @@ def faraday(self, bzk, exk, eyk, dt): def hampere_e1(self, exk, fxy, dt): fk = jnp.fft.fft2(fxy, axes=(0, 1)) - return exk + self.one_over_ikx * jnp.trapz( - jnp.trapz(fk * (jnp.exp(-1j * self.kx[..., None, None] * dt * self.vx) - 1), dx=self.dvy, axis=3), - dx=self.dvx, - axis=2, + return ( + exk + + self.one_over_ikx + * jnp.sum(jnp.sum(fk * (jnp.exp(-1j * self.kx[..., None, None] * dt * self.vx) - 1), axis=3), axis=2) + * self.dvx + * self.dvy ) def hampere_e2(self, eyk, fxy, dt): fk = jnp.fft.fft2(fxy, axes=(0, 1)) - return eyk + self.one_over_iky * jnp.trapz( - jnp.trapz(fk * (jnp.exp(-1j * self.ky[..., None, None] * dt * self.vy) - 1), dx=self.dvy, axis=3), - dx=self.dvx, - axis=2, + return ( + eyk + + self.one_over_iky + * jnp.sum(jnp.sum(fk * (jnp.exp(-1j * self.ky[..., None, None] * dt * self.vy) - 1), axis=3), axis=2) + * self.dvx + * self.dvy ) diff --git a/adept/vlasov2d/pushers/fokker_planck.py b/adept/vlasov2d/pushers/fokker_planck.py index bef9707..baa9798 100644 --- a/adept/vlasov2d/pushers/fokker_planck.py +++ b/adept/vlasov2d/pushers/fokker_planck.py @@ -103,7 +103,7 @@ def __init__(self, cfg): def __call__(self, nu_K, f_xv, dt) -> jnp.ndarray: nu_Kxdt = dt * nu_K[:, :, None, None] exp_nuKxdt = jnp.exp(-nu_Kxdt) - n_prof = jnp.trapz(jnp.trapz(f_xv, axis=3, dx=self.dvy), axis=2, dx=self.dvx) + n_prof = jnp.sum(jnp.sum(f_xv, axis=3), axis=2) * self.dvy * self.dvx return f_xv * exp_nuKxdt + n_prof[:, None] * self.f_mx * (1.0 - exp_nuKxdt) @@ -121,10 +121,10 @@ def __init__(self, cfg): ) def vx_moment(self, f): - return jnp.trapz(f, axis=2, dx=self.dvx) + return jnp.sum(f, axis=2) * self.dvx def vy_moment(self, f): - return jnp.trapz(f, axis=3, dx=self.dvy) + return jnp.sum(f, axis=3) * self.dvy def get_vx_operator( self, nu: jnp.float64, f_xv: jnp.ndarray, dt: jnp.float64 @@ -190,10 +190,10 @@ def __init__(self, cfg): ) def vx_moment(self, f): - return jnp.trapz(f, axis=2, dx=self.dvx) + return jnp.sum(f, axis=2) * self.dvx def vy_moment(self, f): - return jnp.trapz(f, axis=3, dx=self.dvy) + return jnp.sum(f, axis=3) * self.dvy def get_vx_operator( self, nu: jnp.float64, f_xv: jnp.ndarray, dt: jnp.float64 diff --git a/adept/vlasov2d/storage.py b/adept/vlasov2d/storage.py index 2717b6c..51b2382 100644 --- a/adept/vlasov2d/storage.py +++ b/adept/vlasov2d/storage.py @@ -239,7 +239,7 @@ def get_default_save_func(cfg): dvy = cfg["grid"]["dvx"] def _calc_mean_moment_(inp): - return jnp.mean(jnp.trapz(jnp.trapz(inp, dx=dvy, axis=3), dx=dvx, axis=2)) + return jnp.mean(jnp.sum(jnp.sum(inp, axis=3), axis=2)) * dvy * dvx def save(t, y, args): scalars = { diff --git a/configs/envelope-2d/damping.yaml b/configs/envelope-2d/damping.yaml index 8958bc2..eef5035 100644 --- a/configs/envelope-2d/damping.yaml +++ b/configs/envelope-2d/damping.yaml @@ -1,4 +1,4 @@ -mode: envelope-2d +solver: envelope-2d density: offset: 0.9 diff --git a/configs/envelope-2d/epw.yaml b/configs/envelope-2d/epw.yaml index 7260b3b..105810d 100644 --- a/configs/envelope-2d/epw.yaml +++ b/configs/envelope-2d/epw.yaml @@ -1,4 +1,4 @@ -mode: envelope-2d +solver: envelope-2d density: offset: 0.9 diff --git a/configs/envelope-2d/reflection.yaml b/configs/envelope-2d/reflection.yaml index bcd7f47..2ac4264 100644 --- a/configs/envelope-2d/reflection.yaml +++ b/configs/envelope-2d/reflection.yaml @@ -1,4 +1,4 @@ -mode: envelope-2d +solver: envelope-2d density: offset: 0.9 diff --git a/configs/envelope-2d/tpd-opt.yaml b/configs/envelope-2d/tpd-opt.yaml new file mode 100644 index 0000000..e111f84 --- /dev/null +++ b/configs/envelope-2d/tpd-opt.yaml @@ -0,0 +1,74 @@ +models: + bandwidth: + file: None + hyperparams: + input_width: 8 + key: 42 + decoder_width: 16 + decoder_depth: 3 + output_width: 8 + type: GEN +opt: + learning_rate: 0.003 + optimizer: adam +density: + basis: linear + gradient scale length: 200.0um + max: 0.35 + min: 0.18 + noise: + max: 1.0e-09 + min: 1.0e-10 + type: uniform +drivers: + E0: + amplitude_shape: uniform + delta_omega_max: 0.015 + num_colors: 8 +grid: + boundary_abs_coeff: 1.0e4 + boundary_width: 8um + low_pass_filter: 0.7 + dt: 0.002ps + dx: 20nm + tmax: 5.0ps + tmin: 0.0ns + ymax: 5um + ymin: -5um +machine: + calculator: gpu +mlflow: + experiment: tpd-gen-nc-8-nonu + run: kfilt +save: + t: + dt: 100fs + tmax: 5ps + tmin: 0ps + x: + dx: 48nm + y: + dy: 160nm +solver: envelope-2d +terms: + epw: + boundary: + x: absorbing + y: periodic + damping: + collisions: false + landau: true + density_gradient: true + linear: true + source: + noise: true + tpd: true + zero_mask: true +units: + atomic number: 40 + envelope density: 0.25 + ionization state: 6 + laser intensity: 2.0e+15W/cm^2 + laser wavelength: 351nm + reference electron temperature: 2000.0eV + reference ion temperature: 1000eV \ No newline at end of file diff --git a/configs/envelope-2d/tpd.yaml b/configs/envelope-2d/tpd.yaml index cf7ba65..2f6b5e0 100644 --- a/configs/envelope-2d/tpd.yaml +++ b/configs/envelope-2d/tpd.yaml @@ -1,100 +1,62 @@ -mode: envelope-2d - density: - offset: 0.9 - slope: 0.3 + basis: linear + gradient scale length: 200.0um + max: 0.35 + min: 0.18 noise: - min: 1.0e-5 - max: 1.0e-6 + max: 1.0e-09 + min: 1.0e-10 type: uniform - drivers: E0: - w0: 2.0 - t_c: 500. - t_w: 600. - t_r: 20. - x_c: 500. - x_w: 600. - x_r: 20. - y_c: 500. - y_w: 60000000. - y_r: 20. - k0: 1.0 - a0: 0.0 - intensity: 4.0e14 - E2: - w0: 0.03375 - t_c: 230. - t_w: 400. - t_r: 5. - x_c: 1400. - x_w: 600. - x_r: 20. - y_c: 0. - y_w: 2000000. - y_r: 5. - k0: 0.15 - a0: 0.0 - intensity: 4.0e14 - -save: - t: - tmin: 0.0 - tmax: 10000.0 - nt: 32 - -plasma: - wp0: 1.0 - nu_ei: 0.0 - Z: 2 - nb: 1.0 - temperature: 2.0 #keV - density: 2.3e27 #m^3 - -units: - laser wavelength: 351nm - normalizing temperature: 2000eV - normalizing density: 1.5e21/cc - Z: 10 - Zp: 10 - + amplitude_shape: file + file: s3://public-ergodic-continuum/87254/0bb528f5a431439e9f9f295bdcd6d9e7/artifacts/used_driver.pkl + delta_omega_max: 0.015 + num_colors: 8 grid: - xmin: 000.0 - xmax: 5000.0 - nx: 4096 - ymin: -1000.0 - ymax: 1000.0 - ny: 512 - tmin: 0. - tmax: 10000.0 - dt: 2.0 - + boundary_abs_coeff: 1.0e4 + boundary_width: 8um + low_pass_filter: 0.7 + dt: 0.002ps + dx: 20nm + tmax: 5.0ps + tmin: 0.0ns + ymax: 10um + ymin: -10um +machine: + calculator: gpu mlflow: - experiment: lpse2d-tpd - run: noise-test-no-density-gradient - -# models: - # file: None #/Users/archis/Dev/code/ergodic/laplax/weights.eqx - # nu_g: - # activation: tanh - # depth: 4 - # final_activation: tanh - # in_size: 3 - # out_size: 1 - # width_size: 8 - + experiment: tpd-gen-nc-8-nonu + run: ml +save: + t: + dt: 100fs + tmax: 5ps + tmin: 0ps + x: + dx: 48nm + y: + dy: 160nm +solver: envelope-2d terms: epw: - linear: True - density_gradient: True - kinetic real part: False boundary: x: absorbing y: periodic - trapping: - active: False - kld: 0.28 - nuee: 0.0000001 + damping: + collisions: false + landau: true + density_gradient: true + linear: true source: - tpd: False + noise: true + tpd: true + zero_mask: true +units: + atomic number: 40 + envelope density: 0.25 + ionization state: 6 + laser intensity: 2.0e+15W/cm^2 + laser wavelength: 351nm + reference electron temperature: 2000.0eV + reference ion temperature: 1000eV \ No newline at end of file diff --git a/configs/es1d/damping.yaml b/configs/es1d/damping.yaml index 652c05c..a90bfc3 100644 --- a/configs/es1d/damping.yaml +++ b/configs/es1d/damping.yaml @@ -1,4 +1,4 @@ -mode: es-1d +solver: es-1d mlflow: experiment: es1d-epw-test diff --git a/configs/es1d/epw.yaml b/configs/es1d/epw.yaml index 2a64431..979a8df 100644 --- a/configs/es1d/epw.yaml +++ b/configs/es1d/epw.yaml @@ -20,7 +20,7 @@ grid: mlflow: experiment: es1d-epw-test run: nl-fluid-noml -mode: es-1d +solver: es-1d models: file: false nu_g: diff --git a/configs/es1d/es1d.yaml b/configs/es1d/es1d.yaml index 5382d56..aabc466 100644 --- a/configs/es1d/es1d.yaml +++ b/configs/es1d/es1d.yaml @@ -1,4 +1,4 @@ -mode: es-1d +solver: es-1d mlflow: experiment: wavepackets-for-fluid diff --git a/configs/es1d/wp.yaml b/configs/es1d/wp.yaml index bd9c963..aac3e0a 100644 --- a/configs/es1d/wp.yaml +++ b/configs/es1d/wp.yaml @@ -20,7 +20,7 @@ grid: mlflow: experiment: es1d-epw-test run: wp-nl-local -mode: es-1d +solver: es-1d models: file: models/weights.eqx nu_g: diff --git a/configs/sh2d/landau_damping.yaml b/configs/sh2d/landau_damping.yaml index a314b9c..bde43d6 100644 --- a/configs/sh2d/landau_damping.yaml +++ b/configs/sh2d/landau_damping.yaml @@ -1,4 +1,4 @@ -mode: sh-2d +solver: sh-2d mlflow: experiment: sh2d-epw-test diff --git a/configs/tf-1d/damping.yaml b/configs/tf-1d/damping.yaml index bd277fe..41cfa8a 100644 --- a/configs/tf-1d/damping.yaml +++ b/configs/tf-1d/damping.yaml @@ -1,4 +1,4 @@ -mode: tf-1d +solver: tf-1d mlflow: experiment: tf1d-epw-test diff --git a/configs/tf-1d/epw.yaml b/configs/tf-1d/epw.yaml index 57b097d..f31187f 100644 --- a/configs/tf-1d/epw.yaml +++ b/configs/tf-1d/epw.yaml @@ -20,7 +20,7 @@ grid: mlflow: experiment: tf1d-epw-test run: nl-fluid-noml -mode: tf-1d +solver: tf-1d models: file: false nu_g: diff --git a/configs/tf-1d/tf1d.yaml b/configs/tf-1d/tf1d.yaml index d8075f2..b82ebc1 100644 --- a/configs/tf-1d/tf1d.yaml +++ b/configs/tf-1d/tf1d.yaml @@ -1,4 +1,4 @@ -mode: tf-1d +solver: tf-1d mlflow: experiment: wavepackets-for-fluid diff --git a/configs/tf-1d/wp.yaml b/configs/tf-1d/wp.yaml index 2ae5a6b..c106ee6 100644 --- a/configs/tf-1d/wp.yaml +++ b/configs/tf-1d/wp.yaml @@ -23,7 +23,7 @@ mlflow: experiment: tf1d-epw-test run: wp-nl-local -mode: tf-1d +solver: tf-1d models: file: models/weights.eqx diff --git a/configs/vfp-1d/epp-short.yaml b/configs/vfp-1d/epp-short.yaml index 1688e2d..0a724ac 100644 --- a/configs/vfp-1d/epp-short.yaml +++ b/configs/vfp-1d/epp-short.yaml @@ -53,7 +53,7 @@ save: tmax: 50000.0 nt: 6 -mode: vfp-2d +solver: vfp-2d mlflow: experiment: vfp2d diff --git a/configs/vfp-1d/tanh.yaml b/configs/vfp-1d/tanh.yaml index b473c66..bac1133 100644 --- a/configs/vfp-1d/tanh.yaml +++ b/configs/vfp-1d/tanh.yaml @@ -57,7 +57,7 @@ save: tmax: 50000.0 nt: 6 -mode: vfp-2d +solver: vfp-2d mlflow: experiment: vfp2d diff --git a/configs/vlasov-1d/epw.yaml b/configs/vlasov-1d/epw.yaml index 543a7a7..3692190 100644 --- a/configs/vlasov-1d/epw.yaml +++ b/configs/vlasov-1d/epw.yaml @@ -45,7 +45,7 @@ save: tmax: 600.0 nt: 91 -mode: vlasov-1d +solver: vlasov-1d mlflow: experiment: basic-epw-for-plots diff --git a/configs/vlasov-1d/srs.yaml b/configs/vlasov-1d/srs.yaml index a042412..19c8f96 100644 --- a/configs/vlasov-1d/srs.yaml +++ b/configs/vlasov-1d/srs.yaml @@ -45,7 +45,7 @@ save: tmax: 2000.0 nt: 21 -mode: vlasov-1d +solver: vlasov-1d mlflow: experiment: vlasov1d-srs diff --git a/configs/vlasov-1d/wavepacket.yaml b/configs/vlasov-1d/wavepacket.yaml index be7cb87..33322a4 100644 --- a/configs/vlasov-1d/wavepacket.yaml +++ b/configs/vlasov-1d/wavepacket.yaml @@ -43,7 +43,7 @@ grid: mlflow: experiment: wavepacket-k-nu-a-vlasov-hr-sl run: vlasov-absorbing -mode: vlasov-1d +solver: vlasov-1d save: electron: t: diff --git a/configs/vlasov-1d2v/epw.yaml b/configs/vlasov-1d2v/epw.yaml index e304256..c4992a5 100644 --- a/configs/vlasov-1d2v/epw.yaml +++ b/configs/vlasov-1d2v/epw.yaml @@ -55,7 +55,7 @@ save: tmax: 1000.0 nt: 6 -mode: vlasov-1d2v +solver: vlasov-1d2v mlflow: experiment: 1d2v-epw diff --git a/configs/vlasov-2d/base.yaml b/configs/vlasov-2d/base.yaml index e25fde8..fdb0f9d 100644 --- a/configs/vlasov-2d/base.yaml +++ b/configs/vlasov-2d/base.yaml @@ -82,7 +82,7 @@ krook: machine: s-t4 -mode: vlasov-2d +solver: vlasov-2d mlflow: experiment: ld-2d2v diff --git a/efvp.ipynb b/efvp.ipynb deleted file mode 100644 index f742b2b..0000000 --- a/efvp.ipynb +++ /dev/null @@ -1,695 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "ExecuteTime": { - "end_time": "2023-09-29T23:55:47.123239Z", - "start_time": "2023-09-29T23:55:46.826003Z" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "from jax import numpy as jnp\n", - "import numpy as np\n", - "from matplotlib import pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "tags": [] - }, - "outputs": [], - "source": [ - "vmax = 8.\n", - "nv = 1024\n", - "dv = vmax/nv\n", - "v = np.linspace(dv/2, vmax-dv/2, nv)\n", - "nuee = 1e-4\n", - "dt = 0.1" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1.0 1.4999999999974136\n" - ] - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "T0 = 1.0\n", - "\n", - "f00 = np.exp(-v**2./2/T0)\n", - "f00 /= 4*np.pi*np.sum(v**2.*f00)*dv\n", - "\n", - "print(4*np.pi*np.sum(v**2.*f00)*dv, 4*np.pi*np.sum(v**2.*f00*0.5*v**2.)*dv)\n", - "plt.semilogy(v, f00)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(1024,)\n" - ] - } - ], - "source": [ - "ck = 4*np.pi*np.cumsum(f00*v**2.)*dv\n", - "\n", - "inin = (np.sum(f00*v)*dv - np.cumsum(f00*v)*dv)[::-1]\n", - "print(inin.shape)\n", - "\n", - "dk = 4*np.pi/v*np.cumsum(v**2.*inin)*dv" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(ck)\n", - "# plt.plot(inin)\n", - "plt.plot(dk)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/tz/l3jmsqhd7tbfz3rjb276f_3r0000gn/T/ipykernel_72417/2380435860.py:2: RuntimeWarning: overflow encountered in exp\n", - " dlt = 1/w-1/(np.exp(w)-1)\n" - ] - } - ], - "source": [ - "w=dv*ck/dk\n", - "dlt = 1/w-1/(np.exp(w)-1)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(1024,) (1024,) (1024,) (1024,)\n" - ] - } - ], - "source": [ - "print(ck.shape, dk.shape, w.shape, dlt.shape)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjMAAAGdCAYAAADnrPLBAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABAoUlEQVR4nO3deXwV9b3/8ffZsnMgQBaWEBZZBVGh0oALliUi2mJ7+d2iIrSoF6u3LBYFba3UKgKCW0Vc6tJWa6VXaSuIiaAii2wCll2LiAJhhxPIds6Z7++PJAdOwpLtcM5JXs9H05yZ+c7Mdz6B8HbmOzM2Y4wRAABAlLKHuwMAAAC1QZgBAABRjTADAACiGmEGAABENcIMAACIaoQZAAAQ1QgzAAAgqhFmAABAVHOGuwMXgmVZ2rt3rxo1aiSbzRbu7gAAgCowxig/P18tW7aU3X728y8NIszs3btXGRkZ4e4GAACogW+//VatW7c+6/IGEWYaNWokqbQYbre7zrbr9XqVk5OjwYMHy+Vy1dl2UYr6hh41Di3qG1rUN7Qiob4ej0cZGRmBf8fPpkGEmfJLS263u87DTEJCgtxuN3+RQoD6hh41Di3qG1rUN7Qiqb7nGyLCAGAAABDVCDMAACCqEWYAAEBUI8wAAICoRpgBAABRjTADAACiGmEGAABENcIMAACIaoQZAAAQ1QgzAAAgqhFmAABAVCPMAACAqNYgXjQJADg/y1jyWl75LJ98li/w2ev3ymu8leb5TGk7y1iBL2OM/MYvS6WfTy3zy7IsGeOXZflKv4xfluWXMZYsWbIsK7CeMUaSZGSVdi4wz8iodJnf79fOk//RnrVbZbfbS+eXr2essvUrT5c2Oa2tyrZrzGnty6tigrcjBfpWPZXXOftmqr59U422Z9/Imbfhtyzt9ezV5qVL5bCf+9xHy6SWGvm9CbXvSw0RZgAgyvktv44UHdHhosM6XnxcnhKP8ouOyXPygDwFB+UpOqr8Eo8KfQUq8hWpyF+sIn+xCq0SFVleFVo+FRm/isuDQ7TZsSLcPajfvtt03iaXWC7CDADg7I4XH9d3+d/pW883+u7wVn13dKf2F+TpUNERHfTm66gVmhhiM0ZOSS5j5DRGLiM5ZeQ0ZfNUOs8uI4eRbCr9bJNkN5JDkk1G9rJlDkl2U7a8/MsY2aVT88qWq2zeub5LNslINlv5PFvp99Omdfp8BbcLbnv60rPv12YqzDwv2zmmqq5iH6u6wvlbV25RfoxGRn6/Xw6HU7bzbCg9Kb1q/QoRwgwARAif5dNXx77StkObtWPvKu04vEU7CvbpqFVy3nXtxqip31Jjyy+3ZcltGTWyLLnllNsRqyR7jBIcMYp3xCreGa84Z7ziXAmKcyYqPiZJca4ExTrjFeuMl9MZJ5czVg5nnOSIkRyusu8xp6btrtIUYXdINodks5d9tlf47Kjw2V55vmw69a9l+efyf41PXxbM6/Vq4cKFuv766+VyuerkZ4BToqm+hBkACBOv36sNBzdo3Tcf6fPvlmnjid0qkP+MbZv7/MrwedXaZ6m1I17prsZqntBcKYktlOJuo+QmbeVIaC7FJ5/6imssOfg1j/qPP+UAcAEdLTqqpd98qE92vKsVR7boZIXwkmRZ6lJcos5+mzontlSn5I5ql3KJElK6Ss06SI0zCChABfyNAIAQK/GX6OPdufrnv1/RsuPb5TttWTOfX1cUFeuyuFRdnt5bHdtcI3ury6Xkdme9vAIgGGEGAEJk74m9+jD/bU1/+2Hlm1MRpnNxifpbLvVv0VfdOv9I9rZXll4SAlAjhBkAqGMbD2zQ66tmaPHhf8sqO7mS5vPpBq9DN7YZpA49b5VaXs6ZF6COEGYAoI7sOvofPfXJ/Vp8fHvpDJv0/cIi3dqoq67MukeOiwaU3sEDoE4RZgCglo4UHtbcj6do3v6V8tlKb5P+YUGJbm2TrV1FvdT3R7fIEeG3tgLRjDADADVU5CvSX1Y8pj/unK8TttInw11d5NPEDj9Rh36/kteZqG0LF4a7m0C9R5gBgGqyjKUFX7ymZzb8QXnySjapa4lX97YcqD4DHj01mNfrDW9HgQaCMAMA1bB698d6YtlvtNV7TJKU7vPpl40v0dCbnpTd3TK8nQMaKMIMAFTBf458qSc/nqRP8v8jSUq0LN1ub65bhzytuJaXhrdzQANHmAGAczhQcEDPL5+qd/YslWWTnMZoeIldY7N+q6bdh3N7NRABCDMAcAbHi4/rj6tm6M2v/6VilQ7uHVBYovGdb1Hbq+6XnLHh7iKAMoQZADjNocJDevPzOXrrq3eUX/bepMuKijWu+RXq9ZPZUlJqmHsIoCLCDABI2nZ4q95a96z+tW+ZSmQkSR1LSjQ+sbOuum66bGldw9xDAGdDmAHQYB0qPKQPdryj+Vv/qm3FhwLzLykq1s8S2uva6x+Vo1WvMPYQQFUQZgA0GH7Lry+PfamlX/1LH3/9gf5dtD+wzGWMri0o1i3pWbrsuimciQGiCGEGQL1kjNHhosPacXSHtuxZqc+/W64N+V8Hvb1aknoUFWuoI1lDu92sJj1vlRKbhanHAGoqasLMc889p5kzZyovL089e/bUs88+qyuuuCLc3QIQRsYYeUo82nNij/ae2Ks9x3Zqz6Gt2nnsS31ZsE9HrJJK6yRYlr5XVKz+sem6pu1gpXT/f1JqlzD0HkBdiYow87e//U0TJ07U3Llz1adPHz311FPKzs7W9u3blZrKnQVAtDHGyGf55LW8ga8iX5EKfAUq8JZ+nfSdLP1cfFwnCw7JU3BQhwsO6mjxER0p9uio94SO+AtVJOus+7EbozZenzp5vbosppkuT7lUndoNlLPDAM7AAPVIVISZ2bNn64477tDPfvYzSdLcuXO1YMECvfLKK5o8eXLY+vXux3O1fd9G7V+wRna7PXihMbLZJFP2fApTNtum0l/kpR8CjcsW2iRjguYZW/l6NpnyX9qB9conjWQ7fQ9l8wJtzemLTm379FmnzVNZH8ufBWYqtC/9XnGekZEt8FkypZ8rHKexBbeqeCTltbJJ8luWDhzar12L3pfNbgvaV8XjL99N+WfZbKf6bYKPP9DmtGXl61b8LJnAjySojTm9F0GtT2sT3Mez7ev0/z9zGxOoYXX6aYLmGVnlPxlzart+Y3TixAn9c/7cwLqWrKD1SucZyZT/ZFW2rdJ+nd6mdNul3/3Gktf45TWWfCr97DOWvDLyneGnXxvNfH618vnU0udTK1uMMhPS1Sm5ozqk91JcWg+p5aVSTGKd7hNA5Ij4MFNSUqJ169ZpypQpgXl2u10DBw7UypUrz7hOcXGxiouLA9Mej0eS5PV65a3DF7+99fXL+jLeko7X2SZRkVPSkS/D3Yv6zS6p4Gi4e6F4y1K8MUqwLCVaRgnGUoJllGCMEozU2O5SsiNeyc4kJce41TQ2WcmNWqppkw6KT24n424tuVtWCi2Bv/FheOlj+e+buvy9g1Oob2hFQn2ruu+IDzOHDh2S3+9XWlpa0Py0tDRt27btjOtMmzZNU6dOrTQ/JydHCQkJdda35t5EyZyQdOoMx5kebF7hhEiFdrbzr3eObZ2+X6PK8862Ndtp6597vTPv9/S5tjO1O0dfVXZuRqctP9s+bVXYn81UPMtUNv8MvTq9T+ft92mn1Gw6cz2D1jvjz7fyerYKJyUq1uVs2zzTns9ex1M1Dnw3Z5pXYbp8PXNq+7aztrcFzbdJ8sshS3b5jUOSXcY4ZIxTxjikss+WcQa+W8apEhOrIhOnIsWpUDGyOWJlHLGyu1wyMbHyx8TLFxcnK84mE2tkj5PybVK+pG+KJe2XtL9Q0pdlX5EnNzc33F2o16hvaIWzvgUFBVVqF/FhpiamTJmiiRMnBqY9Ho8yMjI0ePBgud3uOtvPIO8g5ebmatCgQXK5XHW2XZTyer2V6mtM6aWT8sslpd8rfFaFNoHP51pWjW1VWEdGss6wjlQ2/wztTdCy0y4HnWFblduXXSo67bhOrXPqElfFdXTadsvb+3x+bd68Wd26dZPd4QhapqB+nNqWTjuW8j5aZVdAHWdYp8RnqaDEr0Kvv/R7hc/5xT4dKyhRobdsI5ZKT6cUnfnPRazTrvbNE9UxNUmd0pLUo5Vbl7RurKTYyPt1dqY/w6g71De0IqG+5VdWzify/vZX0Lx5czkcDu3fvz9o/v79+5Wenn7GdWJjYxUbW/m9KS6XKyQ/kFBtF6Wob+h4vV4tPLRJ1/fJDHuNi7x+HS0o0ZGTJTp60qtDJ4q193ih9hwt1N5jhdpzrFC7jxSoyGtpa16+tublB9a126SuLdy6ol1T9e+cqj7tmirO5Qjj0QTjz3BoUd/QCmd9q7rfiA8zMTEx6tWrlxYvXqxhw4ZJkizL0uLFi3XPPfeEt3MA6kycy6EWjePVonH8Wdv4LaPvjhZoe16+vjxwQlv3ebR+9zHtOVaozXs92rzXo1eX71K8y6ErOzbXsEtbaUDX1IgKNgDqXsSHGUmaOHGiRo0apd69e+uKK67QU089pZMnTwbubgLQMDjsNmU2S1Rms0QNvvjU/H3HC7Xum6Na/tUhLdl2QPs9xcrdsl+5W/arUZxTN1zSUj/r11ad0hqFr/MAQiYqwsx///d/6+DBg3rooYeUl5enSy+9VIsWLao0KBhAw9SicbxuuCReN1zSUsYYbdnn0cJ/79O7n+/R3uNF+uvq3frr6t26plOK7urfQd9vzzNmgPokKsKMJN1zzz1cVgJwXjabTRe3bKyLWzbWvYM667Odh/Xnz77RB5vz9MmOg/pkx0H175yiyUO6qEt63d0QACB8oibMAEB12e029b2oufpe1Fy7DxfopU936q+rd+vj7aWh5tY+mbp/SJeIvBMKQNXZz98EAKJfm2YJemRYd3048RoNvaSFjJH+/Nk3yn5yqT7ZcTDc3QNQC4QZAA1K2+aJeu7my/XG7X2U0TRee44VatQrq/XYwq3y+s/+nicAkYswA6BB6ndRc30w/mqN7ttWkvTi0p265aVVOpB/lqf1AYhYhBkADVZCjFMP//Bizb31ciXFOrV61xH9eM4K/efgiXB3DUA1EGYANHjXdW+hf97TT22bJei7o4X6yfMrtO6bI+HuFoAqIswAgKT2KUn6v7v6qmdGEx0r8Oq2P67Wml0EGiAaEGYAoEyzpFi9dcf3deVFzXWyxK9RrxBogGhAmAGA08THOPTyqN668qLmKigLNJ/vPhrubgE4B8IMAFQQ5yoNNFd1LA00P39tjb46wKBgIFIRZgDgDOJcDr0wsldgDM2oV1Yr7zi3bQORiDADAGeREOPUq6O/p/YpiYGH6x0v8Ia7WwAqIMwAwDk0TYzRn35+hVIbxWr7/nzd+ee1Kvb5w90tAKchzADAebROTtDrP79CjWKdWvX1Ef1q3heyLBPubgEoQ5gBgCro2sKtuSN7yWm36V8b92r6B9vC3SUAZQgzAFBF/S5qrhn/dYkk6YVPdur1FbvC2yEAkggzAFAtP768tSZld5YkPfyvzVq0KS/MPQJAmAGAavpF/w66uU8bGSONe2u91n3DQ/WAcCLMAEA12Ww2/e6HF2tAl1QV+yzd/voa7eRN20DYEGYAoAacDruevfky9WzdWEcLvBr96hodOlEc7m4BDRJhBgBqKCHGqT+O/p7aNE3Q7iMFGvPaGhWU+MLdLaDBIcwAQC00T4rVaz/7npITXNr43XGN/cvnKvLyUD3gQiLMAEAttU9J0sujvqc4l11LdxzUHX9aS6ABLiDCDADUgV6ZyXrtZ1coIcahT788pDGvr1FhCYEGuBAIMwBQR77fvple+9kVSoxxaPlXhzXmz5+rgCE0QMgRZgCgDl3Rrqle//kVSop1as2uo3pqk0PfHi0Id7eAeo0wAwB1rHfbppo3Nktp7ljtL7Rp+Aurte6bI+HuFlBvEWYAIAS6tnDr7//TR60SjA6fLNF/v/CZXv50p4zhbdtAXSPMAECIpLvj9Mvufg3tni6fZfT7BVt155/X8XA9oI4RZgAghOIc0pP/r4ce+dHFinHYlbtlvwbN/kTz1+/hLA1QRwgzABBiNptNI7Pa6p1f9FXXFm4dLfBq/N826LZXVmt7Xn64uwdEPcIMAFwg3Vs11j/v6adfDe6kGIddn355SEOeXqop73yhPccKw909IGoRZgDgAnI57LrnBx2VM+FqDemeLstIf139ra6Z8ZEmvr1BO/ZzpgaoLme4OwAADVHb5ol6/tZeWrvriJ78cIeWf3VY73y+R+98vkffb99U//29DA3p3kJxLke4uwpEPMIMAIRR77ZN9cbt39fGb4/phaX/0fub8vTZziP6bOcRPfSPzRrULU2Du6Xr6k7NlRDDr2zgTPibAQARoGdGE825pZf2HCvU39d+p3nrvtV3RwsDZ2tinXb17dBM32/fTH3aN1P3lm45HYwUACTCDABElFZN4jVuYEf97w8u0ppdR5SzZb9ytuTp2yOF+mj7QX20/aAkKTHGocvaJOvilm51a+lWtxZutWueSMBBg0SYAYAIZLfb1KfsLMyvh3bVtrx8Lf/qkD7beURrdh3R8UKvln11SMu+OhRYJ8ZpV2bTBGU2S1TbZgnKbJ6ozKYJSm8cp7RGcXLHO2Wz2cJ4VEBoEGYAIMLZbDZ1beFW1xZu3X5Ve1mW0ba8fH3x3TFt2efRlr0ebd3n0ckSv748cEJfHjhxxu3EOu1Kc8cpzR2r5kmxapLgUuP4GDWOd6lJgktN4l1qHO9SoziXEmIdSohxKMHlVHyMQzFOzvggchFmACDK2O220ktLLd2BeZZl9O3RAu06XKBvDp/UrkOl3789WqD9nmIdL/Sq2Gdp95EC7T5S/bd4O+02xceUBZwYp+JcpQEnxmGTy2EPfMU4bYopn3bayz6XtnHYbbLbbGXfS4/DYSudV/q5dF5Qm7LPDrtNNltp+9IraTZZfr++OGJTzNYDcjqdskmy2Uq/SlvYVPa/wBmpQBvZyr6rvHGleTbbqenS1cu2cdo2Ty07N5vO3ai2J8zOt35N9u/z+bTnpLQtL18u19njgtNuU/vmSbLbw3fWjzADAPWA3W5TZrNEZTZLlJRSaXmR16+D+cXa7ylSnqdIR06W6FiBV8cLvWXfT017irwqKPGrsMQvn1X6ygWfZZRf5FN+kU9SJL1byqE/bt8Q7k7UY07N+GLleVv99HsZevwnl1yA/pwZYQYAGoA4l0MZTROU0TShWuuV+CwVlvhV4PUFAk5BiV+FXr+8Pktev6USvyWv38jrL5v2VZgum2dZRn5j5LckY4z8ZdPGKPDZsoyssjZWWRvLmFOfLZWtU/p19OgxNW7SpPTUQtm7roxKPxqVTZvyaQW9D6u8Tfms8uWmfKLCvFPtTGCb53Ou92+da/VzbducY81zr1fd/RkVFxcrJib2rGd+ir2W8ot92h7mhz0SZgAAZxXjtCvGaVdjucLdlUq8Xq8WLlyo66/vI5cr8voX7U7Vt/9Z65u7Zb/u+NPaC9yzyhjRBQAAaiXcL4AnzAAAgKhGmAEAADVSPpQmzCdmCDMAACC6EWYAAECNBO5yCvOgGcIMAACIaoQZAABQI5Hyqi/CDAAAqBUGAAMAANQCYQYAANRI+QsseWgeAABALRBmAABAzZQNAD7Xyy8vBMIMAACIaoQZAABQIxFyZzZhBgAA1A4DgAEAAGqBMAMAAGrEZuPWbAAAgFojzAAAgBoJvDQ7rL0gzAAAgChHmAEAADVS79+avWvXLo0ZM0bt2rVTfHy8OnTooN/+9rcqKSkJavfFF1/oqquuUlxcnDIyMjRjxoxK25o3b566dOmiuLg49ejRQwsXLgxVtwEAQDWZMI8ADlmY2bZtmyzL0gsvvKDNmzfrySef1Ny5c/XAAw8E2ng8Hg0ePFiZmZlat26dZs6cqYcfflgvvvhioM2KFSs0YsQIjRkzRuvXr9ewYcM0bNgwbdq0KVRdBwAAUcQZqg1fd911uu666wLT7du31/bt2/X888/riSeekCS98cYbKikp0SuvvKKYmBhdfPHF2rBhg2bPnq0777xTkvT000/ruuuu06RJkyRJjzzyiHJzc/WHP/xBc+fODVX3AQDAedgi5BnAIQszZ3L8+HE1bdo0ML1y5UpdffXViomJCczLzs7W9OnTdfToUSUnJ2vlypWaOHFi0Hays7M1f/78s+6nuLhYxcXFgWmPxyNJ8nq98nq9dXQ0CmyrLreJU6hv6FHj0KK+oUV9Q6sq9fX5fZJKLzOF4udQ1W1esDDz1Vdf6dlnnw2clZGkvLw8tWvXLqhdWlpaYFlycrLy8vIC805vk5eXd9Z9TZs2TVOnTq00PycnRwkJCbU5jDPKzc2t823iFOobetQ4tKhvaFHf0DpXfbcft0lyyOPJD8l41oKCgiq1q3aYmTx5sqZPn37ONlu3blWXLl0C03v27NF1112n4cOH64477qjuLqttypQpQWdzPB6PMjIyNHjwYLnd7jrbj9frVW5urgYNGiSXy1Vn20Up6ht61Di0qG9oUd/Qqkp9m/znsOZsWadGjRrp+uv71nkfyq+snE+1w8y9996r0aNHn7NN+/btA5/37t2ra6+9Vn379g0a2CtJ6enp2r9/f9C88un09PRztilffiaxsbGKjY2tNN/lcoXkD3yototS1Df0qHFoUd/Qor6hda76upylMcJms4Xs39eqqHaYSUlJUUpKSpXa7tmzR9dee6169eqlV199VXZ78M1TWVlZevDBB+X1egMdzs3NVefOnZWcnBxos3jxYo0fPz6wXm5urrKysqrbdQAAEAImzM8ADtmt2Xv27FH//v3Vpk0bPfHEEzp48KDy8vKCxrrcfPPNiomJ0ZgxY7R582b97W9/09NPPx10iWjcuHFatGiRZs2apW3btunhhx/W2rVrdc8994Sq6wAAIIqEbABwbm6uvvrqK3311Vdq3bp10LLyh+s0btxYOTk5uvvuu9WrVy81b95cDz30UOC2bEnq27ev3nzzTf3617/WAw88oI4dO2r+/Pnq3r17qLoOAACqouzO7HC/NTtkYWb06NHnHVsjSZdccok+/fTTc7YZPny4hg8fXkc9AwAA9QnvZgIAADUSKQ/NI8wAAIBaCfNVJsIMAAComXr/1mwAANAw1Nu3ZgMAAFwIhBkAAFAj5VeZGDMDAABQC4QZAABQI7YIGQFMmAEAALUT5utMhBkAAFAjEXJihjADAABqhwHAAAAAtUCYAQAANRK4NZuH5gEAANQcYQYAANQIA4ABAEC9wABgAAAQpSLj1AxhBgAA1EqYx/8SZgAAQHQjzAAAgBopHwBswjxqhjADAACiGmEGAADUSGQM/yXMAACAWmIAMAAAiEq2CHlqHmEGAADUCmdmAAAAaoEwAwAAaiQyLjIRZgAAQJQjzAAAgBqJkPG/hBkAAFA7JswjgAkzAACgRmwRMmqGMAMAAGolzHdmE2YAAEB0I8wAAIAaCbw1m4fmAQAA1BxhBgAARDXCDAAAqBUT5iHAhBkAAFAjPDQPAADUCwwABgAAqAXCDAAAqJHyJwDz0DwAAIBaIMwAAIAaYQAwAACoFxgADAAAohJnZgAAQD3BQ/MAAABqjDADAABqJHBrNmNmAAAAao4wAwAAaoQBwAAAoF7gCcAAACAqRciJGcIMAACoHRPmEcCEGQAAENUIMwAAoEbKBwAzZgYAAKAWCDMAAKCGImMIMGEGAADUCk8ABgAAUYmH5gEAgHqBW7MBAABqgTADAABqpPwqE7dmAwAA1AJhBgAA1IgtQkYAX5AwU1xcrEsvvVQ2m00bNmwIWvbFF1/oqquuUlxcnDIyMjRjxoxK68+bN09dunRRXFycevTooYULF16IbgMAgKpoCLdm33fffWrZsmWl+R6PR4MHD1ZmZqbWrVunmTNn6uGHH9aLL74YaLNixQqNGDFCY8aM0fr16zVs2DANGzZMmzZtuhBdBwAAZxEZ52UuQJh5//33lZOToyeeeKLSsjfeeEMlJSV65ZVXdPHFF+unP/2pfvnLX2r27NmBNk8//bSuu+46TZo0SV27dtUjjzyiyy+/XH/4wx9C3XUAAFAF4R4A7Azlxvfv36877rhD8+fPV0JCQqXlK1eu1NVXX62YmJjAvOzsbE2fPl1Hjx5VcnKyVq5cqYkTJwatl52drfnz5591v8XFxSouLg5MezweSZLX65XX663lUZ1Svq263CZOob6hR41Di/qGFvUNrarU1+fzSZKMTEh+DlXdZsjCjDFGo0eP1tixY9W7d2/t2rWrUpu8vDy1a9cuaF5aWlpgWXJysvLy8gLzTm+Tl5d31n1PmzZNU6dOrTQ/JyfnjKGqtnJzc+t8mziF+oYeNQ4t6hta1De0zlXfQ0WS5JTP6wvJeNaCgoIqtat2mJk8ebKmT59+zjZbt25VTk6O8vPzNWXKlOruotamTJkSdDbH4/EoIyNDgwcPltvtrrP9eL1e5ebmatCgQXK5XHW2XZSivqFHjUOL+oYW9Q2tqtT3myMFemT9MjmdTl1/fXad96H8ysr5VDvM3HvvvRo9evQ527Rv315LlizRypUrFRsbG7Ssd+/euuWWW/T6668rPT1d+/fvD1pePp2enh74fqY25cvPJDY2ttJ+JcnlcoXkD3yototS1Df0qHFoUd/Qor6hda76xjhdQe1Cse+qqHaYSUlJUUpKynnbPfPMM/r9738fmN67d6+ys7P1t7/9TX369JEkZWVl6cEHH5TX6w10ODc3V507d1ZycnKgzeLFizV+/PjAtnJzc5WVlVXdrgMAgBCotwOA27RpEzSdlJQkSerQoYNat24tSbr55ps1depUjRkzRvfff782bdqkp59+Wk8++WRgvXHjxumaa67RrFmzNHToUL311ltau3Zt0O3bAADgwouQZ+aF9wnAjRs3Vk5Ojr7++mv16tVL9957rx566CHdeeedgTZ9+/bVm2++qRdffFE9e/bU3//+d82fP1/du3cPY88BAEC5ML80O7S3Zp+ubdu2Z3xF+CWXXKJPP/30nOsOHz5cw4cPD1XXAABAFOPdTAAAoFZMmEfNEGYAAEBUI8wAAIAaYQAwAACoF8I9AJgwAwAAasQWIadmCDMAAKBWwv3QPMIMAACIaoQZAABQI4GLTIyZAQAAqDnCDAAAqJEIGf9LmAEAALXDE4ABAEBUsikyTs0QZgAAQK3w0DwAAIBaIMwAAIAaKR8AzEPzAAAAaoEwAwAAaiQyhv8SZgAAQC2ZMI8AJswAAICaiZBTM4QZAABQKwwABgAAqAXCDAAAqBGeAAwAAOoFngAMAACiEm/NBgAAqAOEGQAAUCMRcmKGMAMAAGovnA/OI8wAAICoRpgBAAA1YouQEcCEGQAAUGvhvD2bMAMAAGokMs7LEGYAAEAdCOdz8wgzAACgRiJkyAxhBgAA1B63ZgMAANQQYQYAANQIb80GAAD1BgOAAQBA9ImMEzOEGQAAUHs8NA8AAEQdbs0GAAD1hgnjqBnCDAAAiGqEGQAAUCMRcpWJMAMAAGqPAcAAACDq2CJkBDBhBgAARDXCDAAAqJHIOC9DmAEAAHWAMTMAAAA1RJgBAAA1EiHjfwkzAACg9ngCMAAAiDq2CBkCTJgBAAC1xgBgAAAQdRgzAwAA6o0wnpghzAAAgOhGmAEAAFGNMAMAAGrNhHEEMGEGAADUCAOAAQBAvcEAYAAAEHV4aB4AAKg3eGgeAABADRFmAABAjTSIAcALFixQnz59FB8fr+TkZA0bNixo+e7duzV06FAlJCQoNTVVkyZNks/nC2rz8ccf6/LLL1dsbKwuuugivfbaa6HsMgAAqIkwXmZyhmrD//d//6c77rhDjz32mH7wgx/I5/Np06ZNgeV+v19Dhw5Venq6VqxYoX379um2226Ty+XSY489Jkn6+uuvNXToUI0dO1ZvvPGGFi9erNtvv10tWrRQdnZ2qLoOAACqIEJOzIQmzPh8Po0bN04zZ87UmDFjAvO7desW+JyTk6MtW7boww8/VFpami699FI98sgjuv/++/Xwww8rJiZGc+fOVbt27TRr1ixJUteuXbVs2TI9+eSThBkAACKICeOpmZCEmc8//1x79uyR3W7XZZddpry8PF166aWaOXOmunfvLklauXKlevToobS0tMB62dnZuuuuu7R582ZddtllWrlypQYOHBi07ezsbI0fP/6c+y8uLlZxcXFg2uPxSJK8Xq+8Xm8dHaUC26rLbeIU6ht61Di0qG9oUd/Qqkp9/dapAOP1+uT11u25mqr+bEMSZnbu3ClJevjhhzV79my1bdtWs2bNUv/+/bVjxw41bdpUeXl5QUFGUmA6Ly8v8P1MbTwejwoLCxUfH3/G/U+bNk1Tp06tND8nJ0cJCQm1Pr6KcnNz63ybOIX6hh41Di3qG1rUN7TOVd/SLOMMtEt01e2+CwoKqtSuWmFm8uTJmj59+jnbbN26VZZlSZIefPBB/eQnP5Ekvfrqq2rdurXmzZun//mf/6nObqttypQpmjhxYmDa4/EoIyNDgwcPltvtrrP9eL1e5ebmatCgQXK56vgnCOp7AVDj0KK+oUV9Q6sq9fVbRhM+Kw07AwcNVHJCTJ32ofzKyvlUK8zce++9Gj169DnbtG/fXvv27ZMUPEYmNjZW7du31+7duyVJ6enpWr16ddC6+/fvDywr/14+7/Q2brf7rGdlyvcVGxtbab7L5QrJH/hQbRelqG/oUePQor6hRX1D61z1dZx2mcnlrPufQ1W3V60wk5KSopSUlPO269Wrl2JjY7V9+3ZdeeWVkkoT3q5du5SZmSlJysrK0qOPPqoDBw4oNTVVUukpKrfbHQhBWVlZWrhwYdC2c3NzlZWVVZ1uAwCAEKt372Zyu90aO3asfvvb3yonJ0fbt2/XXXfdJUkaPny4JGnw4MHq1q2bRo4cqY0bN+qDDz7Qr3/9a919992Bsypjx47Vzp07dd9992nbtm2aM2eO3n77bU2YMCEU3QYAANUQKQ/NC9lzZmbOnCmn06mRI0eqsLBQffr00ZIlS5ScnCxJcjgceu+993TXXXcpKytLiYmJGjVqlH73u98FttGuXTstWLBAEyZM0NNPP63WrVvr5Zdf5rZsAAAijAnjy5lCFmZcLpeeeOIJPfHEE2dtk5mZWekyUkX9+/fX+vXr67p7AACglmwRcmqGdzMBAIBaq3djZgAAAC4UwgwAAIhqhBkAAFBrYRz/S5gBAAA1FwljgAkzAACg1sL51mzCDAAAqLEIODFDmAEAAHWAMTMAAAA1Q5gBAAA1FglPASbMAACAWuMJwAAAICqF/7wMYQYAANQBHpoHAACiUgQMmSHMAACA2uOheQAAADVEmAEAADVmi4AhwIQZAABQawwABgAA0Sn8J2YIMwAAoPZ4aB4AAIhKEXBiRs5wdyBSWJalkpKSaq3j9XrldDpVVFQkv98fop5FLpfLJYfDEe5uAAAigAnjoBnCjKSSkhJ9/fXXsiyrWusZY5Senq5vv/02Il60FQ5NmjRRenp6gz1+AED4NfgwY4zRvn375HA4lJGRIbu96lfeLMvSiRMnlJSUVK316gNjjAoKCnTgwAFJUosWLcLcIwBAOETCf8s2+DDj8/lUUFCgli1bKiEhoVrrll+aiouLa3BhRpLi4+MlSQcOHFBqaiqXnACgAePW7DAqH+sSExMT5p5Ep/IA6PV6w9wTAEA48NC8CMKYj5qhbgCAcCPMAACAGouE/6YlzNQz/fv31/jx4yVJbdu21VNPPRXW/gAAGoZwjplp8AOA67M1a9YoMTEx3N0AACCkCDP1WEpKSri7AACo5yLgKhOXmaLZyZMnddtttykpKUktWrTQrFmzgpZXvMw0e/Zs9ejRQ4mJicrIyNAvfvELnThxImidl156SRkZGUpISNBNN92k2bNnq0mTJhfgaAAA0cyE8e1MnJmpwBijQm/VXk1gWZYKS/xylvjq5Dkz8S5Hte4OmjRpkj755BP94x//UGpqqh544AF9/vnnuvTSS8/Y3m6365lnnlG7du20c+dO/eIXv9B9992nOXPmSJKWL1+usWPHavr06frhD3+oDz/8UL/5zW9qfVwAgPorEu5qJcxUUOj1q9tDH4Rl31t+l62EmKr9SE6cOKE//vGP+stf/qIBAwZIkl5//XW1bt36rOuUDwyWSs/a/P73v9fYsWMDYebZZ5/VkCFD9Ktf/UqS1KlTJ61YsULvvfdeDY8IANBQ8NA8VNt//vMflZSUqE+fPoF5TZs2VefOnc+6zocffqgBAwaoVatWatSokUaOHKnDhw+roKBAkrR9+3ZdccUVQetUnAYA4HThPy/DmZlK4l0ObflddpXaWpalfE++Grkb1dllplDZtWuXbrjhBt1111169NFH1bRpUy1btkxjxoxRSUlJtV/lAABApCDMVGCz2ap8qceyLPliHEqIcV7wdzN16NBBLpdLq1atUps2bSRJR48e1Y4dO3TNNddUar9u3TpZlqVZs2YF+vr2228HtencubPWrFkTNK/iNAAAZxLGq0yEmWiVlJSkMWPGaNKkSWrWrJlSU1P14IMPnjVUXXTRRfJ6vXr22Wd14403avny5Zo7d25Qm//93//V1VdfrdmzZ+vGG2/UkiVL9P7770fE4C4AQISKgH8iGDMTxWbOnKmrrrpKN954owYOHKgrr7xSvXr1OmPbnj17avbs2Zo+fbq6d++uN954Q9OmTQtq069fP82dO1ezZ89Wz549tWjRIk2YMEFxcXEX4nAAAFHMhHEEMGdmolhSUpL+/Oc/689//nNg3qRJkwKfd+3aFdR+woQJmjBhQtC8kSNHBk3fcccduuOOO4KmL7roojrsNQCgPomAEzOEGQR74oknNGjQICUmJur999/X66+/Hrh1GwCAs2HMDCLG6tWrNWPGDOXn56t9+/Z65plndPvtt4e7WwCACBUJ4yoJMwhS8Q4nAAAiHQOAAQBArfEEYAAAEJUi4CoTYQYAANSF8J2aIcwAAIAai4ATM4QZAABQe4yZAQAAUSkSbs0mzDRQbdu21VNPPRXubgAAUGuEGQAAUGvhfAIwYQYAANRY+C8yEWai2t///nf16NFD8fHxatasmQYOHKiTJ0+qf//+Gj9+fFDbYcOGafTo0UHz8vPzNWLECCUmJqpVq1Z67rnnLlznAQD1SjgHAPM6g4qMkbwFVWtrWaVtSxySvQ5yoSuhyk8f2rdvn0aMGKEZM2bopptuUn5+vj799NNqvYJ95syZeuCBBzR16lR98MEHGjdunDp16qRBgwbV9AgAAA1MBIz/JcxU4i2QHmtZpaZ2SU3qct8P7JViEqvUdN++ffL5fPrxj3+szMxMSVKPHj2qtbt+/fpp8uTJkqROnTpp+fLlevLJJwkzAIBqMzw0D9XVs2dPDRgwQD169NDw4cP10ksv6ejRo9XaRlZWVqXprVu31mU3AQD1XvhPzXBmpiJXQukZkiqwLEue/Hy5GzWSva4uM1WRw+FQbm6uVqxYoZycHD377LN68MEHtWrVKtnt9kqXm7xeb+37BwBABCLMVGSzVflSjyxLcvlL29dFmKkmm82mfv36qV+/fnrooYeUmZmpd999VykpKdq3b1+gnd/v16ZNm3TttdcGrf/ZZ59Vmu7atesF6TsAoH5hADCqbdWqVVq8eLEGDx6s1NRUrVq1SgcPHlTXrl2VmJioiRMnasGCBerQoYNmz56tY8eOVdrG8uXLNWPGDA0bNky5ubmaN2+eFixYcOEPBgAQtRgAjBpzu91aunSpnnrqKXk8HmVmZmrWrFkaMmSIvF6vNm7cqNtuu01Op1MTJkyodFZGku69916tXbtWU6dOldvt1uzZs5WdnR2GowEARDvOzKDaunbtqkWLFp1xmcvl0pw5czRnzpyzrr9r164Q9QwA0JBEwIkZ7mYCAAC1x63ZAAAgKkXCmBnCDAAAiGohCzM7duzQj370IzVv3lxut1tXXnmlPvroo6A2u3fv1tChQ5WQkKDU1FRNmjRJPp8vqM3HH3+syy+/XLGxsbrooov02muvharLAACghsI5ADhkYeaGG26Qz+fTkiVLtG7dOvXs2VM33HCD8vLyJJU++2To0KEqKSnRihUr9Prrr+u1117TQw89FNjG119/raFDh+raa6/Vhg0bNH78eN1+++364IMPQtVtAABQDbYIGAIckjBz6NAhffnll5o8ebIuueQSdezYUY8//rgKCgq0adMmSVJOTo62bNmiv/zlL7r00ks1ZMgQPfLII3ruuedUUlIiSZo7d67atWunWbNmqWvXrrrnnnv0X//1X3ryySdD0W0AABCFQhJmmjVrps6dO+tPf/qTTp48KZ/PpxdeeEGpqanq1auXJGnlypXq0aOH0tLSAutlZ2fL4/Fo8+bNgTYDBw4M2nZ2drZWrlwZim4DAIBqioQBwCF5zozNZtOHH36oYcOGqVHZe4tSU1O1aNEiJScnS5Ly8vKCgoykwHT5paiztfF4PCosLFR8fPwZ919cXKzi4uLAtMfjkVT6fqKK7yjyer0yxsiyLFmWVa3jLH//Ufn6DZFlWTLGyOv1yuFw1Om2y39WvFcqdKhxaFHf0KK+oVXV+pb/W+j1+ur8Z1HV7VUrzEyePFnTp08/Z5utW7eqc+fOuvvuu5WamqpPP/1U8fHxevnll3XjjTdqzZo1atGiRXV2W23Tpk3T1KlTK83PyclRQkLwyxydTqfS09N14sSJwOWt6srPz6/RevVBSUmJCgsLtXTp0kqDt+tKbm5uSLaLU6hxaFHf0KK+oXW++hYVOSTZtHz5Mu1Oqtt9FxQUVKldtcLMvffeq9GjR5+zTfv27bVkyRK99957Onr0qNxutyRpzpw5ys3N1euvv67JkycrPT1dq1evDlp3//79kqT09PTA9/J5p7dxu91nPSsjSVOmTNHEiRMD0x6PRxkZGRo8eHCgP+WKior07bffKikpSXFxcecuQAXGGOXn56tRo0ayRcJ5tjAoKipSfHy8rr766mrX73y8Xq9yc3M1aNAguVyuOt02SlHj0KK+oUV9Q6uq9X18y1IdKylSv35Xqnsr91nb1UT5lZXzqVaYSUlJUUpKynnblScpe4U3Sdvt9sDlmKysLD366KM6cOCAUlNTJZWmP7fbrW7dugXaLFy4MGgbubm5ysrKOuf+Y2NjFRsbW2m+y+Wq9APx+/2y2Wyy2+2V+ns+5cdSvn5DZLfbZbPZzljbuhLKbaMUNQ4t6hta1De0zlff8v+Udzgddf5zqOr2QvIvcFZWlpKTkzVq1Cht3LhRO3bs0KRJkwK3WkvS4MGD1a1bN40cOVIbN27UBx98oF//+te6++67A0Fk7Nix2rlzp+677z5t27ZNc+bM0dtvv60JEyaEotsAAKCaIuHKREjCTPPmzbVo0SKdOHFCP/jBD9S7d28tW7ZM//jHP9SzZ09JksPh0HvvvSeHw6GsrCzdeuutuu222/S73/0usJ127dppwYIFys3NVc+ePTVr1iy9/PLLvNm5zN///nf16NFD8fHxatasmQYOHKiTJ0+qf//+Gj9+fFDbYcOGBV0ibNu2rR555BGNGDFCiYmJatWqlZ577rkLewAAgHqjXr41u3fv3ud9uF1mZmaly0gV9e/fX+vXr6/Lrp2TMUaFvsIqtbUsS4W+Qjm9zjq5zBTvjK9ywt23b59GjBihGTNm6KabblJ+fr4+/fTTwKjyqpg5c6YeeOABTZ06VR988IHGjRunTp06adCgQTU9BAAALriQhZloVegrVJ83+4Rl36tuXqUEV8L5G6o0zPh8Pv34xz9WZmamJKlHjx7V2l+/fv00efJkSVKnTp20fPlyPfnkk4QZAEC1hfHEDC+ajFY9e/bUgAED1KNHDw0fPlwvvfSSjh49Wq1tVBxInZWVpa1bt9ZlNwEA9VwEDJnhzExF8c54rbp5VZXaWpYVuDW7ri4zVZXD4VBubq5WrFihnJwcPfvss3rwwQe1atUq2e32SpebeKgUAKC+IsxUYLPZqnypx7Is+Zw+JbgSwnJrts1mU79+/dSvXz899NBDyszM1LvvvquUlBTt27cv0M7v92vTpk269tprg9b/7LPPKk137dr1gvQdAFC/VGfMZl0jzESpVatWafHixRo8eLBSU1O1atUqHTx4UF27dlViYqImTpyoBQsWqEOHDpo9e7aOHTtWaRvLly/XjBkzNGzYMOXm5mrevHlasGDBhT8YAEDU4jITasztdmvp0qV66qmn5PF4lJmZqVmzZmnIkCHyer3auHGjbrvtNjmdTk2YMKHSWRmp9InOa9eu1dSpU+V2uzV79mxuewcAVMvI72fqeKFXae66fQp8dRBmolTXrl21aNGiMy5zuVyaM2eO5syZc85tuN1uvf3226HoHgCggbjz6g7h7gJ3MwEAgOhGmAEAAFGNy0wN1K5du8LdBQAA6gRnZgAAQFQjzAAAgKhGmCkTzof9RDPLssLdBQBAA9fgx8y4XC7ZbDYdPHhQKSkpVX5rtVT6D3lJSYmKiorC8gTgcDLGqKSkRAcPHpTdbldMTEy4uwQAaKAafJhxOBxq3bq1vvvuu2oPijXGqLCwUPHx8dUKQfVJQkKC2rRp0+DCHAAgcjT4MCNJSUlJ6tixY7Vfxuj1erV06VJdffXVcrlcIepd5HI4HHI6nQ02yAEAIgNhpozD4ZDD4aj2Oj6fT3FxcQ0yzAAAEAm4NgAAAKIaYQYAAEQ1wgwAAIhqDWLMTPkzZDweT51u1+v1qqCgQB6PhzEzIUB9Q48ahxb1DS3qG1qRUN/yf7fP9yy4BhFm8vPzJUkZGRlh7gkAAKiu/Px8NW7c+KzLbaYBPPrWsizt3btXjRo1qtPbiD0ejzIyMvTtt9/K7XbX2XZRivqGHjUOLeobWtQ3tCKhvsYY5efnq2XLlud8nlmDODNjt9vVunXrkG3f7XbzFymEqG/oUePQor6hRX1DK9z1PdcZmXIMAAYAAFGNMAMAAKIaYaYWYmNj9dvf/laxsbHh7kq9RH1DjxqHFvUNLeobWtFU3wYxABgAANRfnJkBAABRjTADAACiGmEGAABENcIMAACIaoSZWnjuuefUtm1bxcXFqU+fPlq9enW4uxTxpk2bpu9973tq1KiRUlNTNWzYMG3fvj2oTVFRke6++241a9ZMSUlJ+slPfqL9+/cHtdm9e7eGDh2qhIQEpaamatKkSfL5fBfyUKLC448/LpvNpvHjxwfmUd/a27Nnj2699VY1a9ZM8fHx6tGjh9auXRtYbozRQw89pBYtWig+Pl4DBw7Ul19+GbSNI0eO6JZbbpHb7VaTJk00ZswYnThx4kIfSsTx+/36zW9+o3bt2ik+Pl4dOnTQI488EvRuHupbdUuXLtWNN96oli1bymazaf78+UHL66qWX3zxha666irFxcUpIyNDM2bMCPWhBTOokbfeesvExMSYV155xWzevNnccccdpkmTJmb//v3h7lpEy87ONq+++qrZtGmT2bBhg7n++utNmzZtzIkTJwJtxo4dazIyMszixYvN2rVrzfe//33Tt2/fwHKfz2e6d+9uBg4caNavX28WLlxomjdvbqZMmRKOQ4pYq1evNm3btjWXXHKJGTduXGA+9a2dI0eOmMzMTDN69GizatUqs3PnTvPBBx+Yr776KtDm8ccfN40bNzbz5883GzduND/84Q9Nu3btTGFhYaDNddddZ3r27Gk+++wz8+mnn5qLLrrIjBgxIhyHFFEeffRR06xZM/Pee++Zr7/+2sybN88kJSWZp59+OtCG+lbdwoULzYMPPmjeeecdI8m8++67QcvropbHjx83aWlp5pZbbjGbNm0yf/3rX018fLx54YUXLtRhGsJMDV1xxRXm7rvvDkz7/X7TsmVLM23atDD2KvocOHDASDKffPKJMcaYY8eOGZfLZebNmxdos3XrViPJrFy50hhT+pfTbrebvLy8QJvnn3/euN1uU1xcfGEPIELl5+ebjh07mtzcXHPNNdcEwgz1rb3777/fXHnllWddblmWSU9PNzNnzgzMO3bsmImNjTV//etfjTHGbNmyxUgya9asCbR5//33jc1mM3v27Ald56PA0KFDzc9//vOgeT/+8Y/NLbfcYoyhvrVRMczUVS3nzJljkpOTg34/3H///aZz584hPqJTuMxUAyUlJVq3bp0GDhwYmGe32zVw4ECtXLkyjD2LPsePH5ckNW3aVJK0bt06eb3eoNp26dJFbdq0CdR25cqV6tGjh9LS0gJtsrOz5fF4tHnz5gvY+8h19913a+jQoUF1lKhvXfjnP/+p3r17a/jw4UpNTdVll12ml156KbD866+/Vl5eXlCNGzdurD59+gTVuEmTJurdu3egzcCBA2W327Vq1aoLdzARqG/fvlq8eLF27NghSdq4caOWLVumIUOGSKK+damuarly5UpdffXViomJCbTJzs7W9u3bdfTo0QtyLA3iRZN17dChQ/L7/UG/7CUpLS1N27ZtC1Ovoo9lWRo/frz69eun7t27S5Ly8vIUExOjJk2aBLVNS0tTXl5eoM2Zal++rKF766239Pnnn2vNmjWVllHf2tu5c6eef/55TZw4UQ888IDWrFmjX/7yl4qJidGoUaMCNTpTDU+vcWpqatByp9Oppk2bNvgaT548WR6PR126dJHD4ZDf79ejjz6qW265RZKobx2qq1rm5eWpXbt2lbZRviw5OTkk/Q/qU8j3AJzF3XffrU2bNmnZsmXh7kq98e2332rcuHHKzc1VXFxcuLtTL1mWpd69e+uxxx6TJF122WXatGmT5s6dq1GjRoW5d9Hv7bff1htvvKE333xTF198sTZs2KDx48erZcuW1BdnxWWmGmjevLkcDkelO0D279+v9PT0MPUqutxzzz1677339NFHH6l169aB+enp6SopKdGxY8eC2p9e2/T09DPWvnxZQ7Zu3TodOHBAl19+uZxOp5xOpz755BM988wzcjqdSktLo7611KJFC3Xr1i1oXteuXbV7925Jp2p0rt8P6enpOnDgQNByn8+nI0eONPgaT5o0SZMnT9ZPf/pT9ejRQyNHjtSECRM0bdo0SdS3LtVVLSPhdwZhpgZiYmLUq1cvLV68ODDPsiwtXrxYWVlZYexZ5DPG6J577tG7776rJUuWVDo12atXL7lcrqDabt++Xbt37w7UNisrS//+97+D/oLl5ubK7XZX+kemoRkwYID+/e9/a8OGDYGv3r1765Zbbgl8pr61069fv0qPE9ixY4cyMzMlSe3atVN6enpQjT0ej1atWhVU42PHjmndunWBNkuWLJFlWerTp88FOIrIVVBQILs9+J8mh8Mhy7IkUd+6VFe1zMrK0tKlS+X1egNtcnNz1blz5wtyiUkSt2bX1FtvvWViY2PNa6+9ZrZs2WLuvPNO06RJk6A7QFDZXXfdZRo3bmw+/vhjs2/fvsBXQUFBoM3YsWNNmzZtzJIlS8zatWtNVlaWycrKCiwvv3V48ODBZsOGDWbRokUmJSWFW4fP4vS7mYyhvrW1evVq43Q6zaOPPmq+/PJL88Ybb5iEhATzl7/8JdDm8ccfN02aNDH/+Mc/zBdffGF+9KMfnfF218suu8ysWrXKLFu2zHTs2LFB3jpc0ahRo0yrVq0Ct2a/8847pnnz5ua+++4LtKG+VZefn2/Wr19v1q9fbySZ2bNnm/Xr15tvvvnGGFM3tTx27JhJS0szI0eONJs2bTJvvfWWSUhI4NbsaPHss8+aNm3amJiYGHPFFVeYzz77LNxdiniSzvj16quvBtoUFhaaX/ziFyY5OdkkJCSYm266yezbty9oO7t27TJDhgwx8fHxpnnz5ubee+81Xq/3Ah9NdKgYZqhv7f3rX/8y3bt3N7GxsaZLly7mxRdfDFpuWZb5zW9+Y9LS0kxsbKwZMGCA2b59e1Cbw4cPmxEjRpikpCTjdrvNz372M5Ofn38hDyMieTweM27cONOmTRsTFxdn2rdvbx588MGg236pb9V99NFHZ/ydO2rUKGNM3dVy48aN5sorrzSxsbGmVatW5vHHH79Qh2iMMcZmzGmPVQQAAIgyjJkBAABRjTADAACiGmEGAABENcIMAACIaoQZAAAQ1QgzAAAgqhFmAABAVCPMAACAqEaYAQAAUY0wAwAAohphBgAARDXCDAAAiGr/H6X1NvaU4VLgAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "supdiag = ck[:-1]*(1-dlt[:-1])+dlt[:-1]/dv\n", - "subdiag = -ck[:-1]*dlt[:-1]+dlt[:-1]/dv\n", - "\n", - "diag = -ck[:-2]*(1-dlt[:-2]) + ck[1:-1]*(dlt[1:-1])-(dlt[1:-1]+dlt[:-2])/dv\n", - "\n", - "diag = np.concatenate([[ck[0]*dlt[0] - dk[0]/dv], diag, [-ck[-2]*(1-dlt[-2])-dk[-2]/dv]])\n", - "plt.plot(diag, label=\"diag\")\n", - "plt.plot(subdiag, label=\"sub\")\n", - "plt.plot(supdiag, label=\"sup\")\n", - "plt.legend()\n", - "plt.grid()" - ] - }, - { - "cell_type": "code", - "execution_count": 340, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "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DNwMIj5GRAAASAZuBhEAAJAUnA4i3DsDAIBdjgYRIggAAMnA0SByGEu8AwBglZtBhAERAACSgptBJI4REQAAbHI0iDAkAgBAMnA0iBxCHAEA1GWMUWWkstm/TBPnLD755JMaOHCg2rRpo44dO2rkyJHav3+/hg8frunTp9fbd8KECbrkkkvir3v27Knf/va3mjhxotq2batjjjlG8+fPT0D1jo6bT9/loXcAgCM4UHNAQxcNbfZ2S35RooxARqP23b17tyZOnKi5c+fqvPPOU3l5uV599dUmhZnbb79dN9xwgwoLC7Vs2TJNmzZNffr00ahRo472FI6am0EEAIAWavfu3aqpqdH555+vHj16SJIGDhzYpGMMGzZM1113nSSpT58+WrNmjX7/+98TRJoPS7wDABpqk9pGJb8osdJuYw0aNEgjRozQwIEDNWbMGI0ePVoXXHCB2rdv3+hjFBQUNHh95513NvrnE8nRIAIAQEM+n6/Rl0hs8fv9Ki4u1muvvably5fr7rvv1qxZs1RSUqKUlJQGl2gikYilnjaOm5NVmSMCAGjBfD6fhg0bpsLCQm3evFlpaWlasmSJOnXqpN27d8f3i0aj2rp1a4OfX7duXYPX/fv397zfR8KICAAALUhJSYlWrFih0aNHKzc3VyUlJfr888/Vv39/tW3bVjNnztRzzz2nvLw8PfDAAyotLW1wjDVr1mju3LmaMGGCiouL9cQTT+i5555r/pORs0Hk0IiIjyXeAQAtTCgU0qpVq3TnnXcqHA6rR48euuOOOzR27FhFIhG98cYbuuSSS+T3+zVjxgydddZZDY5x9dVXa+PGjSosLFQoFNK8efM0ZswYC2fjbBABAKBl6t+/v5YuXXrE9wKBgO69917dc889CofDCoVCSklpOAsjFArp8ccf97qrjeLmHJE4RkQAALDJzSDCZFUAAJICl2YAAHDIjh07bHehHjdHRHjKDAAAScHRIFKLOSIA4LqmPnAOhySqbm4GEeaIAIDzAoGAJKmystJyT1qm6upqSYdWev0hmCMCAHCS3+9Xdna29u7dK0nKyMiQr5X8QzUWi6m6uloHDx484u27iTj+559/royMDKWm/rAo4WgQObygGZdmAMBpnTt3lqR4GGktjDE6cOCA2rRp41m4SklJUffu3X/w8R0NIgAAHHpmS5cuXZSbm5v0D4dr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Sk9Pt92dVicWi+nkk0/W7373O0nS4MGDtXXrVt13332aPHmy5d61fI8//rgeffRRLVq0SCeccIK2bNmi6dOnq2vXrtQX38mpSzM5OTny+/0N7jL47LPP1LlzZ0u9anmmTp2qZ599Vi+//LK6desW3965c2dVV1ertLS03v5169u5c+cj1r/2PZdt2rRJe/fu1Y9//GOlpqYqNTVVK1eu1F133aXU1FTl5eVR3x+gS5cuOv744+tt69+/v3bu3Cnp6/p8198PnTt31t69e+u9X1NToy+//NL5+l5zzTW67rrr9G//9m8aOHCgLrroIs2YMUNFRUWSqG+iJaqeyfB3hlNBJC0tTUOGDNGKFSvi22KxmFasWKGCggKLPWsZjDGaOnWqlixZopdeeqnBcN6QIUMUCATq1Xfbtm3auXNnvL4FBQV666236v3hKC4uVigUavAh4ZoRI0borbfe0pYtW+JfJ598siZNmhT/nvoevWHDhjW43fz9999Xjx49JEm9evVS586d69U3HA6rpKSkXn1LS0u1adOm+D4vvfSSYrGYhg4d2gxnkbwqKyuVklL/I8Xv9ysWi0mivomWqHoWFBRo1apVikQi8X2Ki4vVt2/fZrksI8nN23eDwaBZuHCheeedd8x//dd/mezs7Hp3GeDIrrzyStOuXTvzyiuvmN27d8e/Kisr4/tcccUVpnv37uall14yGzduNAUFBaagoCD+fu3tpaNHjzZbtmwxS5cuNZ06deL20m9R964ZY6jvD7F+/XqTmppqZs+ebT744APz6KOPmoyMDPPII4/E95kzZ47Jzs42zzzzjHnzzTfNueeee8TbIQcPHmxKSkrM6tWrzXHHHefs7aV1TZ482RxzzDHx23efeuopk5OTY37961/H96G+TVNeXm42b95sNm/ebCSZefPmmc2bN5u///3vxpjE1LO0tNTk5eWZiy66yGzdutUsXrzYZGRkcPuu1+6++27TvXt3k5aWZk455RSzbt06211qESQd8evBBx+M73PgwAFz1VVXmfbt25uMjAxz3nnnmd27d9c7zo4dO8zYsWNNmzZtTE5Ojrn66qtNJBJp5rNpGb4ZRKjvD/O3v/3NDBgwwASDQdOvXz/zv//7v/Xej8Vi5sYbbzR5eXkmGAyaESNGmG3bttXb54svvjATJ040mZmZJhQKmUsvvdSUl5c352kkpXA4bKZNm2a6d+9u0tPTTe/evc2sWbPq3RZKfZvm5ZdfPuLfuZMnTzbGJK6eb7zxhjn99NNNMBg0xxxzjJkzZ05znaIxxhifMXWWvQMAAGhGTs0RAQAAyYUgAgAArCGIAAAAawgiAADAGoIIAACwhiACAACsIYgAAABrCCIAAMAagggAALCGIAIAAKwhiAAAAGsIIgAAwJr/D+lYihZPkgezAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "supdiag /= v[1:]**2.*dv\n", - "subdiag /= v[:-1]**2.*dv\n", - "diag /= v**2.*dv\n", - "\n", - "plt.plot(diag, label=\"diag\")\n", - "plt.plot(subdiag, label=\"sub\")\n", - "plt.plot(supdiag, label=\"sup\")\n", - "plt.legend()\n", - "plt.grid()" - ] - }, - { - "cell_type": "code", - "execution_count": 346, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "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NIIKAABwLYJKi5j6AQDAKQQVKyymBQDAcQQVAADgWgQVS4yoAADgNIIKAABwLYJKi1hMCwCAUwgqVlhMCwCA4wgqLTAeRlQAAHAKQcUSIyoAADiNoAIAAFyLoAIAAFyLoGKFxbQAADiOoAIAAFyLoNIi7voBAMApBBVLTP0AAOA0gkoLiCsAADiHoGKFxbQAADiOoAIAAFyLoNIiFtMCAOAUgoolpn4AAHAaQQUAALiWbUFl48aNmjhxonJzc5WUlKTevXvrt7/9rWpra6ParV27VsOHD1diYqKysrI0b948u7rUNo0DKnx7MgAAjom368SfffaZwuGwHnroIfXp00fr1q3TpEmTtHfvXt17772SpGAwqIKCAo0ePVpLlizRxx9/rKuvvlopKSm65ppr7OoaAABoJ2wLKueee67OPffcyHavXr20YcMGPfjgg5GgsmzZMtXW1mrp0qXy+/0aMGCAysvLVVRU5JqgwkoVAACcc1TXqPzwww/q2rVrZLu0tFQjRoyQ3++P7Bs7dqw2bNigXbt2Hc2uNYOIAgCA02wbUfmxL7/8UosWLYqMpkhSZWWlcnNzo9plZGREjnXp0qXJeWpqalRTUxPZDgaDkqRQKKRQKBSz/nrq6iLFieV5cVBjXamvPaivvaivvaivvdxQ39Zeu81BZfr06Zo7d+5h26xfv179+vWLbH/33Xc699xzdemll2rSpEltvWSUwsJCzZ49u8n+4uJiJScnH9G5D9Vl71caIUnyqKSkJGbnRVPU117U117U117U115O1re6urpV7TzGtO1Z8du3b9f3339/2Da9evWKTOds2bJFI0eO1BlnnKHHHntMXu/B2aYrr7xSwWBQzz33XGTfa6+9pn/8x3/Uzp07Wz2ikpWVpR07digQCLTloxyW57v3Ff/YudrrT5Pn5rXy+XwxOzcahEIhlZSUaMyYMdTXBtTXXtTXXtTXXm6obzAYVGpqqn744YfD/vxu84hKWlqa0tLSWtX2u+++0znnnKPBgwfr0UcfjQopkpSfn6+ZM2cqFApFClVSUqK+ffs2G1IkKSEhQQkJCU32+3y+2BY7rrE0ntifG1Gor72or72or72or72crG9rr2vbYtrvvvtOI0eOVHZ2tu69915t375dlZWVqqysjLS57LLL5Pf7NXHiRH3yySd68skntXDhQk2dOtWubrUB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2/qD/WgJh8Pas2ePOnbsKK839qtAjDGqrq7Wtm3bJEnHHXfcTz4XQaVF7f8/SADAT1NfXx8JKd26dXO6OzETDodVW1urxMREW4KKJCUlJUmStm3bpvT09J88DcRiWgAALDSuSUlOTna4J+1TY92OZG0PQcUSUz8AgAY/h+keJ8SibgQVAADgWgQVKyymBQD8zIwcOVI333yzJGngwIFauHChsx1qBRbTtojhPgDAz8/KlSuVmZnpdDdaxIgKAADHoNTU1HaxSJigYompHwBA+7V3715deeWV6tixo4477jjdd999Ucd/PPVTVFSkvLw8dejQQVlZWbr++uu1Z8+eqPc88sgjysrKUnJysi6++GIVFRUpJSXF1s/B1E8LDDM/AIADjDHaF7LnkfMtSfLFtekumltuuUVvvPGGnn/+eaWnp+v222/XBx98oFNOOaXZ9l6vVw888IByc3P19ddf6/rrr9ett96qP/7xj5Kkt99+W9dee63mzp2rCy+8UK+++qruuOOOWHy0wyKoAADQSvtC9Tpp1iuOXPvTu8Yq2d+6H9t79uzRn/70Jz3xxBMaNWqUJOnxxx9Xjx49LN/TuMhWknr27Knf/e53uvbaayNBZdGiRTrvvPP0m9/8RpJ04okn6p133tELL7zwEz9R6zD1YyVy1w9DKgCA9uWrr75SbW2thg4dGtnXtWtX9e3b1/I9r776qkaNGqXjjz9enTp10hVXXKHvv/9e1dXVkqQNGzbo9NNPj3rPj7ftwIgKAACtlOSL06d3jXXs2nbZuHGj/umf/knXXXed5syZo65du+qtt97SxIkTVVtb6+iiW4KKJRbTAgCieTyeVk+/OKl3797y+XwqKytTdna2JGnXrl36/PPPdfbZZzdpv2bNGoXDYd13332R7/556qmnotr07dtX7733XtS+H2/bwf3VdhxTPwCA9qVjx46aOHGibrnlFnXr1k3p6emaOXOm5RcQ9unTR6FQSIsWLdIFF1ygt99+W0uWLIlq8x//8R8aMWKEioqKdMEFF2jlypV66aWXbP96AdaoAADwMzR//nwNHz5cF1xwgUaPHq2zzjpLgwcPbrbtoEGDVFRUpLlz5+rkk0/WsmXLVFhYGNVm2LBhWrJkiYqKijRo0CC9/PLLmjJlihITE239HIyoWDmwmJYJIABAe9SxY0f9+c9/1p///OfI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Cx4MBpWVlaXNmzcrEAjE9NygvnajvvaivvaivvZyQ32NMaqqqlL37t0P+5yVdj+i4vV61aNHD1uvEQgE+INiI+prL+prL+prL+prL6fre7iRlEYspgUAAK5FUAEAAK5FUDmMhIQE/fa3v1VCQoLTXflZor72or72or72or72ak/1bfeLaQEAwM8XIyoAAMC1CCoAAMC1CCoAAMC1CCoAAMC1CCoWFi9erJ49eyoxMVFDhw7V6tWrne5Su1BYWKh/+Id/UKdOnZSenq6LLrpIGzZsiGqzf/9+TZ48Wd26dVPHjh31z//8z9q6dWtUm02bNun8889XcnKy0tPTdcstt6iuru5ofhTXu+eee+TxeHTzzTdH9lHbI/fdd9/p17/+tbp166akpCTl5eXp/fffjxw3xmjWrFk67rjjlJSUpNGjR+uLL76IOsfOnTt1+eWXKxAIKCUlRRMnTtSePXuO9kdxnfr6et1xxx3Kzc1VUlKSevfurbvvvjvqu16ob+u9+eabuuCCC9S9e3d5PB4999xzUcdjVcu1a9dq+PDhSkxMVFZWlubNm2f3R4tm0MTy5cuN3+83S5cuNZ988omZNGmSSUlJMVu3bnW6a643duxY8+ijj5p169aZ8vJy84tf/MJkZ2ebPXv2RNpce+21Jisry6xYscK8//775owzzjBnnnlm5HhdXZ05+eSTzejRo82HH35oXnzxRZOammpmzJjhxEdypdWrV5uePXuagQMHmptuuimyn9oemZ07d5qcnBwzYcIEU1ZWZr7++mvzyiuvmC+//DLS5p577jGdO3c2zz33nPnoo4/MhRdeaHJzc82+ffsibc4991wzaNAg8+6775pVq1aZPn36mHHjxjnxkVxlzpw5plu3buaFF14w33zzjXn66adNx44dzcKFCyNtqG/rvfjii2bmzJnmmWeeMZLMs88+G3U8FrX84YcfTEZGhrn88svNunXrzF/+8heTlJRkHnrooaP1MQ1BpRmnn366mTx5cmS7vr7edO/e3RQWFjrYq/Zp27ZtRpJ54403jDHG7N692/h8PvP0009H2qxfv95IMqWlpcaYhj98Xq/XVFZWRto8+OCDJhAImJqamqP7AVyoqqrKnHDCCaakpMScffbZkaBCbY/cbbfdZs466yzL4+Fw2GRmZpr58+dH9u3evdskJCSYv/zlL8YYYz799FMjybz33nuRNi+99JLxeDzmu+++s6/z7cD5559vrr766qh9l1xyibn88suNMdT3SPw4qMSqln/84x9Nly5dov5+uO2220zfvn1t/kQHMfXzI7W1tVqzZo1Gjx4d2ef1ejV69GiVlpY62LP26YcffpAkde3aVZK0Zs0ahUKhqPr269dP2dnZkfqWlpYqLy9PGRkZkTZjx45VMBjUJ598chR7706TJ0/W+eefH1VDidrGwn//939ryJAhuvTSS5Wenq5TTz1VjzzySOT4N998o8rKyqgad+7cWUOHDo2qcUpKioYMGRJpM3r0aHm9XpWVlR29D+NCZ555plasWKHPP/9ckvTRRx/prbfe0nnnnSeJ+sZSrGpZWlqqESNGyO/3R9qMHTtWGzZs0K5du47KZ2n3X0oYazt27FB9fX3UX+SSlJGRoc8++8yhXrVP4XBYN998s4YNG6aTTz5ZklRZWSm/36+UlJSothkZGaqsrIy0aa7+jceOZcuXL9cHH3yg9957r8kxanvkvv76az344IOaOnWqbr/9dr333nu68cYb5ff7NX78+EiNmqvhoTVOT0+POh4fH6+uXbse8zWePn26gsGg+vXrp7i4ONXX12vOnDm6/PLLJYn6xlCsallZWanc3Nwm52g81qVLF1v6H9Un26+AY9bkyZO1bt06vfXWW0535Wdh8+bNuummm1RSUqLExESnu/OzFA6HNWTIEP3+97+XJJ166qlat26dlixZovHjxzvcu/bvqaee0rJly/Rf//VfGjBggMrLy3XzzTere/fu1BeWmPr5kdTUVMXFxTW5U2Lr1q3KzMx0qFftzw033KAXXnhBr732mnr06BHZn5mZqdraWu3evTuq/aH1zczMbLb+jceOVWvWrNG2bdt02mmnKT4+XvHx8XrjjTf0wAMPKD4+XhkZGdT2CB133HE66aSTovb1799fmzZtknSwRof7+yEzM1Pbtm2LOl5XV6edO3ce8zW+5ZZbNH36dP3qV79SXl6errjiCk2ZMkWFhYWSqG8sxaqWbvg7g6DyI36/X4MHD9aKFSsi+8LhsFasWKH8/HwHe9Y+GGN0ww036Nlnn9XKlSubDBkOHjxYPp8vqr4bNmzQpk2bIvXNz8/Xxx9/HPUHqKSkRIFAoMkPkWPJqFGj9PHHH6u8vDzya8iQIbr88ssjr6ntkRk2bFiT2+k///xz5eTkSJJyc3OVmZkZVeNgMKiysrKoGu/evVtr1qyJtFm5cqXC4bCGDh16FD6Fe1VXV8vrjf6xExcXp3A4LIn6xlKsapmfn68333xToVAo0qakpER9+/Y9KtM+krg9uTnLly83CQkJ5rHHHjOffvqpueaaa0xKSkrUnRJo3nXXXWc6d+5sXn/9dVNRURH5VV1dHWlz7bXXmuzsbLNy5Urz/vvvm/z8fJOfnx853ngLbUFBgSkvLzcvv/yySUtL4xbaZhx6148x1PZIrV692sTHx5s5c+aYL774wixbtswkJyebJ554ItLmnnvuMSkpKeb55583a9euNb/85S+bveXz1FNPNWVlZeatt94yJ5xwwjF5++yPjR8/3hx//PGR25OfeeYZk5qaam699dZIG+rbelVVVebDDz80H374oZFkioqKzIcffmi+/fZbY0xsarl7926TkZFhrrjiCrNu3TqzfPlyk5yczO3JbrBo0SKTnZ1t/H6/Of300827777rdJfaBUnN/nr00Ucjbfbt22euv/5606VLF5OcnGwuvvhiU1FREXWejRs3mvPOO88kJSWZ1NRUM23aNBMKhY7yp3G/HwcVanvk/v73v5uTTz7ZJCQkmH79+pmHH3446ng4HDZ33HGHycjIMAkJCWbUqFFmw4YNUW2+//57M27cONOxY0cTCATMVVddZaqqqo7mx3ClYDBobrrpJpOdnW0SExNNr169zMyZM6NufaW+rffaa681+/ft+PHjjTGxq+VHH31kzjrrLJOQkGCOP/54c8899xytj2iMMcZjzCGPBAQAAHAR1qgAAADXIqgAAADXIqgAAADXIqgAAADXIqgAAADXIqgAAADXIqgAAADXIqgAAADXIqgAAADXIqgAAADXIqgAAADXIqgAAADX+v+5fN+pbhA/UwAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# supdiag *= -nuee*dt\n", - "# subdiag *= -nuee*dt\n", - "# diag = 1+nuee*dt*diag\n", - "\n", - "plt.plot(diag, label=\"diag\")\n", - "plt.plot(subdiag, label=\"sub\")\n", - "plt.plot(supdiag, label=\"sup\")\n", - "plt.legend()\n", - "plt.grid()" - ] - }, - { - "cell_type": "code", - "execution_count": 284, - "metadata": {}, - "outputs": [], - "source": [ - "test_f = np.exp(-(v-4)**2.)\n", - "test_f /= np.sum(v**2.*test_f)*4*np.pi*dv" - ] - }, - { - "cell_type": "code", - "execution_count": 285, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 285, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(v, test_f)" - ] - }, - { - "cell_type": "code", - "execution_count": 286, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Copyright (c) Ergodic LLC 2023\n", - "# research@ergodic.io\n", - "\n", - "from jax import numpy as jnp\n", - "from jax.lax import scan\n", - "import equinox as eqx\n", - "\n", - "\n", - "class TridiagonalSolver(eqx.Module):\n", - " num_unroll: int\n", - "\n", - " def __init__(self, cfg):\n", - " super(TridiagonalSolver, self).__init__()\n", - " self.num_unroll = 8\n", - "\n", - " @staticmethod\n", - " def compute_primes(last_primes, x):\n", - " \"\"\"\n", - " This function is a single iteration of the forward pass in the non-in-place Thomas\n", - " tridiagonal algorithm\n", - "\n", - " :param last_primes:\n", - " :param x:\n", - " :return:\n", - " \"\"\"\n", - "\n", - " last_cp, last_dp = last_primes\n", - " a, b, c, d = x\n", - " cp = c / (b - a * last_cp)\n", - " dp = (d - a * last_dp) / (b - a * last_cp)\n", - " new_primes = jnp.stack((cp, dp))\n", - " return new_primes, new_primes\n", - "\n", - " @staticmethod\n", - " def backsubstitution(last_x, x):\n", - " \"\"\"\n", - " This function is a single iteration of the backward pass in the non-in-place Thomas\n", - " tridiagonal algorithm\n", - "\n", - " :param last_x:\n", - " :param x:\n", - " :return:\n", - " \"\"\"\n", - " cp, dp = x\n", - " new_x = dp - cp * last_x\n", - " return new_x, new_x\n", - "\n", - " def __call__(self, a, b, c, d):\n", - " \"\"\"\n", - " Solves a tridiagonal matrix system with diagonals a, b, c and RHS vector d.\n", - "\n", - " This uses the non-in-place Thomas tridiagonal algorithm.\n", - "\n", - " The NumPy version, on the other hand, uses the in-place algorithm.\n", - "\n", - " :param a: (2D float array (nx, nv)) represents the subdiagonal of the linear operator\n", - " :param b: (2D float array (nx, nv)) represents the main diagonal of the linear operator\n", - " :param c: (2D float array (nx, nv)) represents the super diagonal of the linear operator\n", - " :param d: (2D float array (nx, nv)) represents the right hand side of the linear operator\n", - " :return:\n", - " \"\"\"\n", - "\n", - " diags_stacked = jnp.stack([arr.transpose((1, 0)) for arr in (a, b, c, d)], axis=1)\n", - " _, primes = scan(self.compute_primes, jnp.zeros((2, *a.shape[:-1])), diags_stacked, unroll=self.num_unroll)\n", - " _, sol = scan(self.backsubstitution, jnp.zeros(a.shape[:-1]), primes[::-1], unroll=self.num_unroll)\n", - " return sol[::-1].transpose((1, 0))\n" - ] - }, - { - "cell_type": "code", - "execution_count": 287, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "tds = TridiagonalSolver(None)" - ] - }, - { - "cell_type": "code", - "execution_count": 288, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "out = np.squeeze(tds(np.concatenate([[0.], subdiag])[None, :], diag[None, :], np.concatenate([supdiag, [0.]])[None, :], test_f[None, :]))" - ] - }, - { - "cell_type": "code", - "execution_count": 289, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def calc_dens(this_f):\n", - " return np.sum(this_f*v**2.)*4*np.pi*dv\n", - "\n", - "def calc_intenergy(this_f):\n", - " return np.sum(0.5*this_f*v**4.)*4*np.pi*dv" - ] - }, - { - "cell_type": "code", - "execution_count": 290, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.9999999999999999 1.0202183 9.23484775361025 9.401089\n" - ] - }, - { - "data": { - "image/png": "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1a8AGDduHEVFRcyfP59bb73V5urC35///Gf+9Kc/8frrrzNy5EgKCgq49957SUtL0/6VE9LprXaUnJyM0+n8whUvZWVlpKam2lRV+Ln77rt5++23+eCDD+jfv39geWpqKvX19VRWVgaNP37/pqamtrj/m9d1VatXr+bAgQOcf/75REREEBERwb///W+efvppIiIiSElJ0b49S3379mXEiBFBy4YPH05xcTFwbB+d7PshNTWVAwcOBK1vbGykvLy8y+/jH//4xzzwwAPccMMNZGZmcvPNN/PDH/6QefPmAdq/bamt9mUofGco9LSjqKgoxo8fz/LlywPLfD4fy5cvJzs728bKwoMxhrvvvpu//e1vvP/++184LDp+/HgiIyOD9u+WLVsoLi4O7N/s7GwKCwuD/jIuW7aM+Pj4L/xC6kouv/xyCgsLKSgoCDwmTJjAjTfeGPiz9u3ZufDCC78wxcLWrVsZOHAgABkZGaSmpgbtY4/HQ35+ftA+rqysZPXq1YEx77//Pj6fj6ysrA74FKGruroahyP4V5jT6cTn8wHav22prfZldnY2H330EQ0NDYExy5YtY+jQoR1yagvQJevtbcGCBSY6Otq8+uqrZuPGjWbmzJkmMTEx6IoXadmdd95pEhISzIcffmj2798feFRXVwfGfPe73zUDBgww77//vlm1apXJzs422dnZgfXNl1VfccUVpqCgwCxdutT07t1bl1W34Pirt4zRvj1bK1asMBEREebRRx8127ZtM3/6059MXFyc+eMf/xgY89hjj5nExETz97//3axfv95ce+21LV4GPG7cOJOfn28+/vhjM2TIkC55SfXn3XrrraZfv36BS9bffPNNk5ycbO6///7AGO3f03fkyBGzdu1as3btWgOY//mf/zFr1641e/bsMca0zb6srKw0KSkp5uabbzZFRUVmwYIFJi4uTpesdzbPPPOMGTBggImKijITJ040n332md0lhQWgxccrr7wSGFNTU2O+973vmZ49e5q4uDjz1a9+1ezfvz9oO7t37zZXXXWViY2NNcnJyeZHP/qRaWho6OBPE/o+H3q0b8/eP/7xDzNq1CgTHR1thg0bZl588cWg9T6fzzz88MMmJSXFREdHm8svv9xs2bIlaMzhw4fN9OnTTffu3U18fLy57bbbzJEjRzryY4Qkj8dj7rnnHjNgwAATExNjzjnnHPPTn/406HJo7d/T98EHH7T4fXvrrbcaY9puX65bt85MmTLFREdHm379+pnHHnusoz6iMcYYy5jjpq8UERER6aTU0yMiIiJdgkKPiIiIdAkKPSIiItIlKPSIiIhIl6DQIyIiIl2CQo+IiIh0CQo9IiIi0iUo9IiIiEiXoNAjIiIiXYJCj4iIiHQJCj0iIiLSJSj0iIiISJfw/wEJhxRhp/STzQAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(out)\n", - "plt.plot(test_f)\n", - "\n", - "print(calc_dens(test_f), calc_dens(out), calc_intenergy(test_f), calc_intenergy(out))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 332, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2.880374e-13\n", - "1.9476737e-10\n", - "7.493978e-10\n", - "1.6642718e-09\n", - "2.9392067e-09\n", - "4.574281e-09\n", - "6.569535e-09\n", - "8.925092e-09\n" - ] - }, - { - "data": { - "image/png": "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39O5QXxPZz/xHZ0bxPd0bhDf07lBfE/nBvE9nf1+i9/R7yYhnCAIgiAIgiAIgiCcrUTLuSAIgiAIgiAIgiC0MhGcC4IgCIIgCIIgCEIrE8G5IAiCIAiCIAiCILQyEZwLgiAIgiAIgiAIQisTwbkgCIIgCIIgCIIgtDIRnJ9lXn/9ddq0aYPVamXAgAFs27attasknGbdunVccMEFJCUlIUkSX331VWtXSfiBp59+mn79+uFwOIiLi2PatGkcPXq0tasl/MCbb75J9+7dCQsLIywsjEGDBvHdd9+1drWE/8MzzzyDJEnceeedrV0V4TSPPPIIkiSdcevYsWNrV0v4gZMnT3LFFVcQHR2NzWajW7du7Nixo7WrJZymTZs2//ZbkiSJW265pbWrJpxGURQeeughMjIysNlsZGZm8vjjj/NbmIRMBOdnkc8//5y77rqLhx9+mF27dtGjRw/GjRtHeXl5a1dNCHA6nfTo0YPXX3+9tasi/Adr167llltuYcuWLaxYsQKfz8fYsWNxOp2tXTXhNCkpKTzzzDPs3LmTHTt2cP755zN16lQOHjzY2lUT/oPt27fz9ttv071799auitCCLl26UFJSErxt2LChtasknKampoYhQ4ZgMpn47rvvOHToEC+88AKRkZGtXTXhNNu3bz/jd7RixQoAZsyY0co1E0737LPP8uabb/Laa69x+PBhnn32WZ577jn+8Y9/tHbV/mdinvOzyIABA+jXrx+vvfYaAKqqkpqaym233cb999/fyrUTfkiSJBYuXMi0adNauyrCj6ioqCAuLo61a9cybNiw1q6O8COioqJ4/vnnue6661q7KsIPNDY20rt3b9544w2eeOIJevbsycsvv9za1RICHnnkEb766iv27NnT2lUR/oP777+fjRs3sn79+tauivAT3HnnnSxevJicnBwkSWrt6ggBkydPJj4+nvfffz/42vTp07HZbMyZM6cVa/a/Ey3nZwmv18vOnTsZPXp08DVZlhk9ejSbN29uxZoJwrmtrq4O0AM/4eykKApz587F6XQyaNCg1q6O0IJbbrmFSZMmnfE3Sji75OTkkJSURNu2bbn88sspKCho7SoJp/n666/p27cvM2bMIC4ujl69evHuu++2drWEH+H1epkzZw7XXnutCMzPMoMHD2bVqlVkZ2cDsHfvXjZs2MCECRNauWb/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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "test_f = np.exp(-(v-4)**2.)\n", - "test_f /= np.sum(v**2.*test_f)*4*np.pi*dv\n", - "exp_old_f = test_f \n", - "\n", - "test_f = np.exp(-(v-4)**2.)\n", - "test_f /= np.sum(v**2.*test_f)*4*np.pi*dv\n", - "imp_old_f = test_f \n", - "\n", - "dt = 0.001\n", - "speed = 3.\n", - "\n", - "fig, ax = plt.subplots(2, 1, figsize=(12, 4))\n", - "\n", - "for i in range(200):\n", - " subdiag = np.ones_like(v)*speed*dt/2/dv\n", - " supdiag = -np.ones_like(v)*speed*dt/2/dv\n", - " diag = np.ones_like(v)\n", - " \n", - " exp_new_f = exp_old_f + speed*dt*np.gradient(exp_old_f)/dv\n", - " exp_old_f = exp_new_f\n", - " if i % 25 == 0:\n", - " ax[0].plot(v, exp_new_f)\n", - " \n", - " imp_new_f = tds(subdiag[None, :], diag[None, :], supdiag[None, :], imp_old_f[None, :])[0]\n", - " imp_old_f = imp_new_f\n", - " if i % 25 == 0:\n", - " ax[1].plot(v, imp_new_f)\n", - " \n", - " print(np.sum((imp_new_f-exp_new_f)**2.))" - ] - }, - { - "cell_type": "code", - "execution_count": 348, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import xarray as xr" - ] - }, - { - "cell_type": "code", - "execution_count": 387, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "tst = xr.open_dataset(\"/Users/archis/Dev/code/ergodic/adept/mlruns/967378829355502545/635967fafac34ee7b383b90f8fbc1971/artifacts/binary/scalar-fields.nc\")" - ] - }, - { - "cell_type": "code", - "execution_count": 388, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "KeysView(\n", - "Dimensions: (t: 64, x: 32, y: 2)\n", - "Coordinates:\n", - " * t (t) float64 0.5 3.508 6.516 9.524 12.53 ... 181.0 184.0 187.0 190.0\n", - " * x (x) float64 0.3272 0.9816 1.636 2.29 ... 18.65 19.3 19.96 20.61\n", - " * y (y) float64 -24.0 24.0\n", - "Data variables:\n", - " n (t, x, y) float64 ...\n", - " T (t, x, y) float64 ...)" - ] - }, - "execution_count": 388, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tst.keys()" - ] - }, - { - "cell_type": "code", - "execution_count": 400, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "nk1 = np.abs(np.fft.rfft(tst[\"n\"].data[..., 0], axis=1)[:, 1])\n", - "tax = tst.coords[\"t\"].data\n", - "dt = tax[1]-tax[0]\n", - "ts = 40" - ] - }, - { - "cell_type": "code", - "execution_count": 402, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 402, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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t0dsbCxycnL01rl48SKmT58OZ2dnuLi4YPbs2aipqenEvbh519vfxsZGLFiwACEhIXB0dISPjw9mzJiBoqIivW209udhyZIlnbwnN3ajY/vII49ctR9jxozRW8dcji2AVv8OC4KA9957T7eOqRzb9sbC0opNmzYhPj4eixcvRlZWFkJDQxEXF4eysjKpo92yPXv2YP78+UhNTcWuXbvQ2NiI0aNHo7a2Vm+9uXPnori4WLe8++67EiW+NQMGDNDbj99//1333j//+U/88MMP+Oabb7Bnzx4UFRXhvvvukzDtrdm/f7/evu7atQsAMHnyZN06pnpca2trERoaihUrVrT6/rvvvouPPvoIq1atQlpaGhwdHREXF4f6+nrdOtOnT8fRo0exa9cubNu2DXv37sVjjz3WWbtgkOvtb11dHbKysrBw4UJkZWVhy5YtOHnyJO69996r1n3jjTf0jvfTTz/dGfENcqNjCwBjxozR248NGzbovW8uxxaA3n4WFxdjzZo1EAQB999/v956pnBs251IV4mKihLnz5+v+71GoxF9fHzExMRECVN1jLKyMhGAuGfPHt1rw4cPF5999lnpQrWTxYsXi6Ghoa2+V1lZKVpbW4vffPON7rXjx4+LAMSUlJROStixnn32WbFXr16iVqsVRdF8jisA8bvvvtP9XqvVil5eXuJ7772ne62yslK0tbUVN2zYIIqiKB47dkwEIO7fv1+3zs8//ywKgiCeP3++07K3xd/3tzXp6ekiADE/P1/3mp+fn/jBBx90bLh21tq+zpw5U5wwYcI1P2Pux3bChAninXfeqfeaKR7b9sAzLH+jVquRmZmJ2NhY3WsymQyxsbFISUmRMFnHqKqqAgC4urrqvf7VV1/Bzc0NAwcOREJCAurq6qSId8tycnLg4+ODwMBATJ8+HQUFBQCAzMxMNDY26h3n4OBg9OzZ0yyOs1qtxpdffolHH31U74Gg5nJc/yovLw8lJSV6x1KhUECpVOqOZUpKClxcXBAZGalbJzY2FjKZDGlpaZ2eub1VVVVBEAS4uLjovb5kyRJ069YN4eHheO+999DU1CRNwFuUnJwMDw8PBAUFYd68eaioqNC9Z87HtrS0FD/++CNmz5591XvmcmwNYRYPP2xP5eXl0Gg08PT01Hvd09MTJ06ckChVx9BqtXjuuedw2223YeDAgbrXH3zwQfj5+cHHxweHDh3CggULcPLkSWzZskXCtIZTKpVYt24dgoKCUFxcjNdffx3Dhg3DkSNHUFJSAhsbm6u+wXt6eqKkpESawO1o69atqKysxCOPPKJ7zVyO69+1HK/W/s62vFdSUgIPDw+9962srODq6mryx7u+vh4LFizAtGnT9B6S98wzz2Dw4MFwdXXFvn37kJCQgOLiYixbtkzCtIYbM2YM7rvvPgQEBOD06dN45ZVXMHbsWKSkpEAul5v1sf3iiy/g5OR01aVqczm2hmJhsWDz58/HkSNH9MZ1ANC79hsSEgJvb2+MGjUKp0+fRq9evTo7ZpuNHTtW9+tBgwZBqVTCz88Pmzdvhr29vYTJOt7q1asxduxY+Pj46F4zl+NKf2psbMQDDzwAURSxcuVKvffi4+N1vx40aBBsbGzw+OOPIzEx0aRu9z516lTdr0NCQjBo0CD06tULycnJGDVqlITJOt6aNWswffp02NnZ6b1uLsfWULwk9Ddubm6Qy+VXzRYpLS2Fl5eXRKna31NPPYVt27bh119/RY8ePa67rlKpBADk5uZ2RrQO4+Ligr59+yI3NxdeXl5Qq9WorKzUW8ccjnN+fj52796NOXPmXHc9czmuLcfren9nvby8rho039TUhIsXL5rs8W4pK/n5+di1a5fe2ZXWKJVKNDU14ezZs50TsIMEBgbCzc1N9+fWHI8tAPz22284efLkDf8eA+ZzbG+EheVvbGxsEBERgaSkJN1rWq0WSUlJiImJkTBZ+xBFEU899RS+++47/PLLLwgICLjhZ7KzswEA3t7eHZyuY9XU1OD06dPw9vZGREQErK2t9Y7zyZMnUVBQYPLHee3atfDw8MC4ceOuu565HNeAgAB4eXnpHUuVSoW0tDTdsYyJiUFlZSUyMzN16/zyyy/QarW64mZKWspKTk4Odu/ejW7dut3wM9nZ2ZDJZFddPjE1586dQ0VFhe7Prbkd2xarV69GREQEQkNDb7iuuRzbG5J61K8x2rhxo2hrayuuW7dOPHbsmPjYY4+JLi4uYklJidTRbtm8efNEhUIhJicni8XFxbqlrq5OFEVRzM3NFd944w0xIyNDzMvLE7///nsxMDBQvOOOOyRObrjnn39eTE5OFvPy8sQ//vhDjI2NFd3c3MSysjJRFEXxiSeeEHv27Cn+8ssvYkZGhhgTEyPGxMRInPrWaDQasWfPnuKCBQv0Xjf141pdXS0eOHBAPHDggAhAXLZsmXjgwAHdrJglS5aILi4u4vfffy8eOnRInDBhghgQECBevnxZt40xY8aI4eHhYlpamvj777+Lffr0EadNmybVLl3X9fZXrVaL9957r9ijRw8xOztb7+9xQ0ODKIqiuG/fPvGDDz4Qs7OzxdOnT4tffvml6O7uLs6YMUPiPbva9fa1urpafOGFF8SUlBQxLy9P3L17tzh48GCxT58+Yn19vW4b5nJsW1RVVYkODg7iypUrr/q8KR3b9sbCcg0ff/yx2LNnT9HGxkaMiooSU1NTpY7ULgC0uqxdu1YURVEsKCgQ77jjDtHV1VW0tbUVe/fuLb744otiVVWVtMHbYMqUKaK3t7doY2Mjdu/eXZwyZYqYm5ure//y5cvik08+KXbt2lV0cHAQJ02aJBYXF0uY+Nbt2LFDBCCePHlS73VTP66//vprq39uZ86cKYpi89TmhQsXip6enqKtra04atSoq/4fVFRUiNOmTRO7dOkiOjs7i7NmzRKrq6sl2Jsbu97+5uXlXfPv8a+//iqKoihmZmaKSqVSVCgUop2dndivXz/x7bff1vshbyyut691dXXi6NGjRXd3d9Ha2lr08/MT586de9U/Hs3l2Lb45JNPRHt7e7GysvKqz5vSsW1vgiiKYoeewiEiIiK6RRzDQkREREaPhYWIiIiMHgsLERERGT0WFiIiIjJ6LCxERERk9FhYiIiIyOixsBAREZHRY2EhIiIio8fCQkREREaPhYWIiIiMHgsLERERGT0WFiIiIjJ6/x/JjZ0ZQHs4WAAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(tax, np.abs(nk1))\n", - "plt.plot(tax[-ts:], np.abs(nk1[-ts:]))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 403, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-0.011994095250511719\n" - ] - } - ], - "source": [ - "measured_damping_rate = np.mean(np.gradient(nk1[-32:], dt) / nk1[-32:])\n", - "print(measured_damping_rate)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/export_runs.py b/export_runs.py new file mode 100644 index 0000000..016df8e --- /dev/null +++ b/export_runs.py @@ -0,0 +1,24 @@ +import os +from tqdm import tqdm + +os.environ["MLFLOW_TRACKING_URI"] = "/pscratch/sd/a/archis/mlflow" +os.environ["MLFLOW_ENABLE_ARTIFACTS_PROGRESS_BAR"] = "False" + +from utils.misc import export_run + +if __name__ == "__main__": + with open("/global/homes/a/archis/adept/completed_run_ids.txt", "r") as f: + run_ids = f.read().split("\n") + + with open("/global/homes/a/archis/adept/uploaded_run_ids.txt", "r") as f: + uploaded_run_ids = f.read().split("\n") + left_run_ids = list(set(run_ids) - set(uploaded_run_ids)) + + print(f"found {len(run_ids)} completed runs") + print(f"found {len(uploaded_run_ids)} uploaded runs") + print(f"uploading {len(left_run_ids)} runs") + + for run_id in tqdm(left_run_ids): + export_run(run_id) + with open("/global/homes/a/archis/adept/uploaded_run_ids.txt", "a") as f: + f.write(run_id + "\n") diff --git a/exporter.sh b/exporter.sh new file mode 100644 index 0000000..bb16d81 --- /dev/null +++ b/exporter.sh @@ -0,0 +1,18 @@ +#!/bin/bash +#SBATCH --qos=regular +#SBATCH -A m4490 +#SBATCH --time=12:00:00 +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=1 +#SBATCH --constraint=cpu + +# export PYTHONPATH='$PYTHONPATH:/global/homes/a/archis/adept/' +export BASE_TEMPDIR='/pscratch/sd/a/archis/tmp/' +export MLFLOW_TRACKING_URI='/pscratch/sd/a/archis/mlflow' +# export JAX_ENABLE_X64=True +# export MLFLOW_EXPORT=True +# export MLFLOW_ENABLE_ARTIFACTS_PROGRESS_BAR=False + +source /pscratch/sd/a/archis/venvs/adept-cpu/bin/activate +cd /global/u2/a/archis/adept/ +srun python export_runs.py \ No newline at end of file diff --git a/nersc-gpu.sh b/nersc-gpu.sh index 0e13630..70c2b9c 100644 --- a/nersc-gpu.sh +++ b/nersc-gpu.sh @@ -1,8 +1,8 @@ #!/bin/bash #SBATCH -A m4490_g -#SBATCH -C gpu +#SBATCH -C gpu&hbm80g #SBATCH -q shared -#SBATCH -t 2:00:00 +#SBATCH -t 20:00:00 #SBATCH -n 1 #SBATCH -c 32 #SBATCH --gpus-per-task=1 @@ -13,9 +13,8 @@ export MLFLOW_TRACKING_URI="$PSCRATCH/mlflow" export MLFLOW_EXPORT=True # copy job stuff over -module load python +source /pscratch/sd/a/archis/venvs/adept-gpu/bin/activate module load cudnn/8.9.3_cuda12.lua -module load cudatoolkit/12.0.lua -conda activate adept-gpu -cd /global/u2/a/archis/adept/ \ No newline at end of file +cd /global/u2/a/archis/adept/ +srun python3 tpd_learn.py \ No newline at end of file diff --git a/nersc-workflow.sh b/nersc-workflow.sh new file mode 100644 index 0000000..166b19c --- /dev/null +++ b/nersc-workflow.sh @@ -0,0 +1,9 @@ +#!/bin/bash +#SCRON -q workflow +#SCRON -A m4490 +#SCRON -t 30-00:00:00 +#SCRON -o output-%j.out +#SCRON --open-mode=append + +0 0 */5 * * /pscratch/sd/a/archis/venvs/adept-cpu/bin/python3 /global/u2/a/archis/adept/tpd_learn.py + diff --git a/requirements-cpu.txt b/requirements-cpu.txt new file mode 100644 index 0000000..36b3811 --- /dev/null +++ b/requirements-cpu.txt @@ -0,0 +1,19 @@ +jaxlib==0.4.26 +jax==0.4.26 +diffrax +matplotlib +scipy +numpy +tqdm +xarray +mlflow +flatdict +h5netcdf +optax +jaxopt +boto3 +pint +mlflow_export_import +plasmapy +tabulate +interpax \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 884d742..8e5c5e7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -jax -jaxlib +jaxlib==0.4.26+cuda12.cudnn89 +jax==0.4.26 diffrax matplotlib scipy diff --git a/tests/test_lpse2d/configs/epw.yaml b/tests/test_lpse2d/configs/epw.yaml index 02332e2..6324bdf 100644 --- a/tests/test_lpse2d/configs/epw.yaml +++ b/tests/test_lpse2d/configs/epw.yaml @@ -1,4 +1,4 @@ -mode: envelope-2d +solver: envelope-2d density: basis: uniform diff --git a/tests/test_lpse2d/configs/resonance_search.yaml b/tests/test_lpse2d/configs/resonance_search.yaml index f63e018..0c3e9ca 100644 --- a/tests/test_lpse2d/configs/resonance_search.yaml +++ b/tests/test_lpse2d/configs/resonance_search.yaml @@ -1,4 +1,4 @@ -mode: envelope-2d +solver: envelope-2d density: basis: uniform diff --git a/tests/test_lpse2d/test_epw_frequency.py b/tests/test_lpse2d/test_epw_frequency.py index 0997088..70c08a5 100644 --- a/tests/test_lpse2d/test_epw_frequency.py +++ b/tests/test_lpse2d/test_epw_frequency.py @@ -9,7 +9,7 @@ from numpy import testing from utils.runner import run -from theory.electrostatic import get_roots_to_electrostatic_dispersion, get_nlfs +from adept.theory.electrostatic import get_roots_to_electrostatic_dispersion, get_nlfs def _real_part_(kinetic): diff --git a/tests/test_lpse2d/test_resonance.py b/tests/test_lpse2d/test_resonance.py index 4980bd0..519af9a 100644 --- a/tests/test_lpse2d/test_resonance.py +++ b/tests/test_lpse2d/test_resonance.py @@ -22,7 +22,7 @@ from tqdm import tqdm from adept.lpse2d.core import integrator -from theory.electrostatic import get_roots_to_electrostatic_dispersion +from adept.theory.electrostatic import get_roots_to_electrostatic_dispersion def load_cfg(rand_k0, kinetic, adjoint): @@ -96,7 +96,7 @@ def get_loss(state, pulse_dict, mod_defaults): def loss(w0): pulse_dict["drivers"]["E2"]["w0"] = w0 - vf = integrator.VectorField(mod_defaults) + vf = integrator.SpectralPotential(mod_defaults) results = diffeqsolve( terms=ODETerm(vf), solver=integrator.Stepper(), diff --git a/tests/test_tf1d/configs/resonance.yaml b/tests/test_tf1d/configs/resonance.yaml index f7bdb50..308059b 100644 --- a/tests/test_tf1d/configs/resonance.yaml +++ b/tests/test_tf1d/configs/resonance.yaml @@ -1,4 +1,4 @@ -mode: tf-1d +solver: tf-1d mlflow: experiment: tf1d-ions-test diff --git a/tests/test_tf1d/configs/resonance_search.yaml b/tests/test_tf1d/configs/resonance_search.yaml index 65f9c99..21926c8 100644 --- a/tests/test_tf1d/configs/resonance_search.yaml +++ b/tests/test_tf1d/configs/resonance_search.yaml @@ -1,4 +1,4 @@ -mode: tf-1d +solver: tf-1d mlflow: experiment: tf1d-resonance-search diff --git a/tests/test_tf1d/configs/vlasov_comparison.yaml b/tests/test_tf1d/configs/vlasov_comparison.yaml index 12972f3..18b5cd6 100644 --- a/tests/test_tf1d/configs/vlasov_comparison.yaml +++ b/tests/test_tf1d/configs/vlasov_comparison.yaml @@ -1,4 +1,4 @@ -mode: tf-1d +solver: tf-1d mlflow: experiment: tf1d-ions-test diff --git a/tests/test_tf1d/test_against_vlasov.py b/tests/test_tf1d/test_against_vlasov.py index 1e73215..12964b8 100644 --- a/tests/test_tf1d/test_against_vlasov.py +++ b/tests/test_tf1d/test_against_vlasov.py @@ -11,7 +11,7 @@ import mlflow import xarray as xr -from theory import electrostatic +from adept.theory import electrostatic from utils.runner import run @@ -47,6 +47,7 @@ def test_single_resonance(): with mlflow.start_run(run_name=mod_defaults["mlflow"]["run"]) as mlflow_run: result, datasets = run(mod_defaults) + result, state, args = result vds = xr.open_dataset("tests/test_tf1d/vlasov-reference/all-fields-kx.nc", engine="h5netcdf") nk1_fluid = result.ys["kx"]["electron"]["n"]["mag"][:, 1] diff --git a/tests/test_tf1d/test_landau_damping.py b/tests/test_tf1d/test_landau_damping.py index d3e5e35..bbd1d3b 100644 --- a/tests/test_tf1d/test_landau_damping.py +++ b/tests/test_tf1d/test_landau_damping.py @@ -11,7 +11,7 @@ from jax import numpy as jnp import mlflow -from theory import electrostatic +from adept.theory import electrostatic from utils.runner import run @@ -47,6 +47,7 @@ def test_single_resonance(): # modify config with mlflow.start_run(run_name=mod_defaults["mlflow"]["run"]) as mlflow_run: result, datasets = run(mod_defaults) + result, state, args = result kx = ( np.fft.fftfreq( diff --git a/tests/test_tf1d/test_resonance.py b/tests/test_tf1d/test_resonance.py index 58f8dcf..999389e 100644 --- a/tests/test_tf1d/test_resonance.py +++ b/tests/test_tf1d/test_resonance.py @@ -11,7 +11,7 @@ from jax import numpy as jnp import mlflow -from theory import electrostatic +from adept.theory import electrostatic from utils.runner import run @@ -49,6 +49,7 @@ def test_single_resonance(gamma): with mlflow.start_run(run_name=mod_defaults["mlflow"]["run"]) as mlflow_run: result, datasets = run(mod_defaults) + result, state, args = result kx = ( np.fft.fftfreq( mod_defaults["save"]["x"]["nx"], d=mod_defaults["save"]["x"]["ax"][2] - mod_defaults["save"]["x"]["ax"][1] diff --git a/tests/test_tf1d/test_resonance_search.py b/tests/test_tf1d/test_resonance_search.py index c079cc2..a545fc0 100644 --- a/tests/test_tf1d/test_resonance_search.py +++ b/tests/test_tf1d/test_resonance_search.py @@ -21,7 +21,7 @@ from tqdm import tqdm from adept.tf1d import helpers -from theory.electrostatic import get_roots_to_electrostatic_dispersion +from adept.theory.electrostatic import get_roots_to_electrostatic_dispersion def load_cfg(rand_k0, gamma, adjoint): @@ -100,7 +100,7 @@ def run_one_step(i, w0, vg_func, mod_defaults, optimizer, opt_state): mlflow.log_metrics({"run_time": round(time.time() - t0, 4)}) with tempfile.TemporaryDirectory() as td: t0 = time.time() - helpers.post_process(results, mod_defaults, td) + helpers.post_process((results, None, None), mod_defaults, td) mlflow.log_metrics({"postprocess_time": round(time.time() - t0, 4), "loss": float(loss)}) # log artifacts mlflow.log_artifacts(td) @@ -119,8 +119,8 @@ def get_vg_func(gamma, adjoint): defaults["grid"] = helpers.get_solver_quantities(cfg=defaults) defaults = helpers.get_save_quantities(defaults) - pulse_dict = {"drivers": defaults["drivers"]} - state = helpers.init_state(defaults, td=None) + # pulse_dict = {"drivers": defaults["drivers"]} + state, pulse_dict = helpers.init_state(defaults, td=None) loss_fn = get_loss(state, pulse_dict, defaults) vg_func = eqx.filter_jit(jax.value_and_grad(loss_fn, argnums=0, has_aux=True)) diff --git a/tests/test_tf1d/vlasov-reference/config.yaml b/tests/test_tf1d/vlasov-reference/config.yaml index 903aa5b..d3c97e8 100644 --- a/tests/test_tf1d/vlasov-reference/config.yaml +++ b/tests/test_tf1d/vlasov-reference/config.yaml @@ -100,7 +100,7 @@ machine: local mlflow: experiment: landau_damping run: test -mode: calculator +solver: calculator nu: time-profile: baseline: 0.0001 diff --git a/tests/test_vfp1d/epp-short.yaml b/tests/test_vfp1d/epp-short.yaml index c746975..91ab2d8 100644 --- a/tests/test_vfp1d/epp-short.yaml +++ b/tests/test_vfp1d/epp-short.yaml @@ -54,7 +54,7 @@ save: tmax: 50000.0 nt: 6 -mode: vfp-2d +solver: vfp-2d mlflow: experiment: vfp2d diff --git a/tests/test_vfp1d/test_kappa_eh.py b/tests/test_vfp1d/test_kappa_eh.py index f5fcbf2..98375e1 100644 --- a/tests/test_vfp1d/test_kappa_eh.py +++ b/tests/test_vfp1d/test_kappa_eh.py @@ -11,10 +11,6 @@ def _run_(Z, ee): cfg["units"]["Z"] = Z - if ee: - cfg["terms"]["fokker_planck"]["flm"]["ee"] = True - cfg["grid"]["nv"] = 2048 - if ee: cfg["terms"]["fokker_planck"]["flm"]["ee"] = True cfg["grid"]["nv"] = 2048 @@ -24,6 +20,7 @@ def _run_(Z, ee): with mlflow.start_run(run_name=cfg["mlflow"]["run"]) as mlflow_run: result, datasets = run(cfg) + result, state, args = result dataT = datasets["fields"]["fields-T keV"].data np.testing.assert_almost_equal(np.mean(dataT[-4, :]), np.mean(dataT[4, :]), decimal=5) diff --git a/tests/test_vlasov1d/configs/resonance.yaml b/tests/test_vlasov1d/configs/resonance.yaml index 4900458..e8e917f 100644 --- a/tests/test_vlasov1d/configs/resonance.yaml +++ b/tests/test_vlasov1d/configs/resonance.yaml @@ -47,7 +47,7 @@ save: tmax: 480.0 nt: 9 -mode: vlasov-1d +solver: vlasov-1d mlflow: experiment: vlasov1d diff --git a/tests/test_vlasov1d/test_landau_damping.py b/tests/test_vlasov1d/test_landau_damping.py index edec95d..9a60f62 100644 --- a/tests/test_vlasov1d/test_landau_damping.py +++ b/tests/test_vlasov1d/test_landau_damping.py @@ -12,7 +12,7 @@ import mlflow -from theory import electrostatic +from adept.theory import electrostatic from utils.runner import run @@ -65,6 +65,7 @@ def test_single_resonance(real_or_imag, time, field, edfdv): # modify config with mlflow.start_run(run_name=mod_defaults["mlflow"]["run"]) as mlflow_run: result, datasets = run(mod_defaults) + result, _state_, _args_ = result efs = result.ys["fields"]["e"] ek1 = 2.0 / mod_defaults["grid"]["nx"] * np.fft.fft(efs, axis=1)[:, 1] ek1_mag = np.abs(ek1) diff --git a/tests/test_vlasov2d/configs/damping.yaml b/tests/test_vlasov2d/configs/damping.yaml index f686218..366b218 100644 --- a/tests/test_vlasov2d/configs/damping.yaml +++ b/tests/test_vlasov2d/configs/damping.yaml @@ -81,7 +81,7 @@ krook: machine: s-t4 -mode: vlasov-2d +solver: vlasov-2d mlflow: experiment: ld-2d2v diff --git a/tests/test_vlasov2d/test_landau_damping.py b/tests/test_vlasov2d/test_landau_damping.py index 876bc60..cdd81ff 100644 --- a/tests/test_vlasov2d/test_landau_damping.py +++ b/tests/test_vlasov2d/test_landau_damping.py @@ -12,7 +12,7 @@ import mlflow -from theory import electrostatic +from adept.theory import electrostatic from utils.runner import run diff --git a/tpd_learn.py b/tpd_learn.py new file mode 100644 index 0000000..1559037 --- /dev/null +++ b/tpd_learn.py @@ -0,0 +1,201 @@ +from parsl.app.app import python_app +import logging, os +import equinox as eqx + +logger = logging.getLogger(__name__) + +if "BASE_TEMPDIR" in os.environ: + BASE_TEMPDIR = os.environ["BASE_TEMPDIR"] +else: + BASE_TEMPDIR = None + +from utils import misc + + +def run_one_val_and_grad(model_path, Te, L, I0, cfg_path, run_id): + """ + This function is the main entry point for running a simulation. It takes a configuration dictionary and returns a + ``diffrax.Solution`` object and a dictionary of datasets. + + Args: + cfg: A dictionary containing the configuration for the simulation. + + Returns: + A tuple of a Solution object and a dictionary of ``xarray.dataset``s. + + """ + + import os, logging + + logger = logging.getLogger(__name__) + + if "BASE_TEMPDIR" in os.environ: + BASE_TEMPDIR = os.environ["BASE_TEMPDIR"] + else: + BASE_TEMPDIR = None + + os.environ["XLA_PYTHON_CLIENT_PREALLOCATE"] = "false" + + import mlflow, yaml + from utils.misc import export_run + from utils.runner import run + + # log to logger + logging.info(f"Running a run") + + with open(cfg_path, "r") as fi: + cfg = yaml.safe_load(fi) + + logging.info(f"Config is loaded") + + cfg["density"]["gradient scale length"] = f"{L}um" + cfg["units"]["laser intensity"] = f"{I0:.2e}W/cm^2" + cfg["units"]["reference electron temperature"] = f"{Te}eV" + + cfg["models"]["bandwidth"]["file"] = model_path + cfg["mode"] = "train-bandwidth" + + with mlflow.start_run(run_id=run_id) as mlflow_run: + solver_output, postprocessing_output = run(cfg) + mlflow.log_artifact(model_path) + + export_run(mlflow_run.info.run_id) + + val = solver_output[0][0] + grad = solver_output[1] + + return val, grad + + +if __name__ == "__main__": + import uuid + from itertools import product + from tqdm import tqdm + + logging.basicConfig(filename=f"runlog-tpd-learn-{str(uuid.uuid4())[-4:]}.log", level=logging.INFO) + + # use the logger to note that we're running a parsl job + logging.info("Running with parsl") + + import jax + from jax.flatten_util import ravel_pytree + + jax.config.update("jax_platform_name", "cpu") + jax.config.update("jax_enable_x64", True) + + import optax + + misc.setup_parsl("gpu", 4) + run_one_val_and_grad = python_app(run_one_val_and_grad) + + import yaml, mlflow, tempfile, os + import numpy as np, equinox as eqx + from adept.lpse2d import nn + + with open(f"/global/homes/a/archis/adept/configs/envelope-2d/tpd.yaml", "r") as fi: + cfg = yaml.safe_load(fi) + + mlflow.set_experiment(cfg["mlflow"]["experiment"]) + + with mlflow.start_run(run_name="learn-tpd") as mlflow_run: + with tempfile.TemporaryDirectory(dir=BASE_TEMPDIR) as td: + with open(os.path.join(td, "config.yaml"), "w") as fi: + yaml.dump(cfg, fi) + mlflow.log_artifacts(td) + misc.log_params(cfg) + + parent_run_id = mlflow_run.info.run_id + misc.export_run(parent_run_id) + + # create the dataset with the appropriate independent variables + input_names = ("Te", "L", "I0") + + # 125 simulations in total + Tes = np.linspace(2000, 4000, 3) + Ls = np.linspace(150, 450, 4) + I0s = np.logspace(14, 16, 7) + + rng = np.random.default_rng(487) + + # batch logic + all_inputs = np.array(list(product(Tes, Ls, I0s))) + + batch_size = 12 + num_batches = all_inputs.shape[0] // batch_size + batch_inds = np.arange(num_batches) + + # restart mlflow run that was initialized in the optimizer + # we did that over there so that the appropriate nesting of the mlflow run can take place + # remember this is a separate process than what is happening in __main__ + with mlflow.start_run(run_id=parent_run_id, log_system_metrics=True) as mlflow_run: + opt = optax.adam(learning_rate=cfg["opt"]["learning_rate"]) + + if cfg["models"]["bandwidth"]["type"] == "VAE": + model = nn.DriverVAE(**cfg["models"]["bandwidth"]["hyperparams"]) + elif cfg["models"]["bandwidth"]["type"] == "MLP": + model = nn.DriverModel(**cfg["models"]["bandwidth"]["hyperparams"]) + else: + raise ValueError("Invalid model type") + + opt_state = opt.init(eqx.filter(model, eqx.is_array)) # initialize the optimizer state + + with tempfile.TemporaryDirectory( + dir=BASE_TEMPDIR + ) as td: # create a temporary directory for optimizer run artifacts + os.makedirs(os.path.join(td, "model-history"), exist_ok=True) # create a directory for model history + with open(cfg_path := os.path.join(td, "config.yaml"), "w") as fi: + yaml.dump(cfg, fi) + + for i in range(1000): # 1000 epochs + rng.shuffle(all_inputs) + + for j, batch_ind in tqdm(enumerate(batch_inds), total=num_batches): # iterate over the batches + nn.save( + model_path := os.path.join(td, "model-history", f"model-e-{i}-b-{j}.eqx"), + cfg["models"]["bandwidth"], + model, + ) # save the model + mlflow.log_artifacts(td) + misc.export_run(parent_run_id, prefix="artifact", step=i) + # this model and model_path are passed to the run_one_val_and_grad function for use in the simulation + + batch_loss = 0.0 # initialize the batch loss + + batch = all_inputs[batch_ind * batch_size : (batch_ind + 1) * batch_size] # get the batch + val_and_grads = [] # initialize the list to store the values and gradient Futures + run_ids = [] + for Te, L, I0 in batch: + + with mlflow.start_run(nested=True, run_name=f"epoch={i}-{Te=}-{L=}-{I0=:.2e}") as nested_run: + mlflow.log_params({"indep_var.Te": Te, "indep_var.L": L, "indep_var.I0": I0}) + + # get the futures for all the inputs + val_and_grads.append( + run_one_val_and_grad(model_path, Te, L, I0, cfg_path, run_id=nested_run.info.run_id) + ) + run_ids.append(nested_run.info.run_id) # store the run_id + + # for run_id in prev_run_ids: + # artifact_dir = mlflow.get_artifact_uri(run_id) + # shutil.rmtree(artifact_dir) + + vgs = [vg.result() for vg in val_and_grads] # get the results of the futures + val = np.mean([v for v, _ in vgs]) # get the mean of the loss values + + avg_grad = misc.all_reduce_gradients( + [g for _, g in vgs], batch_size + ) # get the average of the gradients + flat_grad, _ = ravel_pytree(avg_grad) + mlflow.log_metrics({"batch grad norm": float(np.linalg.norm(flat_grad))}) + + # with open("./completed_run_ids.txt", "a") as f: + # f.write("\n".join(run_ids) + "\n") + + mlflow.log_metrics({"batch loss": float(val)}, step=i * batch_size + j) + misc.export_run(parent_run_id, prefix="parent", step=i) + updates, opt_state = opt.update(avg_grad["bandwidth"], opt_state, model) + model = eqx.apply_updates(model, updates) + + batch_loss += val + + mlflow.log_metrics({"epoch loss": float(batch_loss / num_batches)}, step=i) diff --git a/tpd_opt.py b/tpd_opt.py new file mode 100644 index 0000000..8523fc2 --- /dev/null +++ b/tpd_opt.py @@ -0,0 +1,139 @@ +from parsl.app.app import python_app +import logging, os +import equinox as eqx +import pickle + +logger = logging.getLogger(__name__) + +if "BASE_TEMPDIR" in os.environ: + BASE_TEMPDIR = os.environ["BASE_TEMPDIR"] +else: + BASE_TEMPDIR = None + +from utils import misc + + +def run_one_val_and_grad(cfg, run_id): + import os + + os.environ["XLA_PYTHON_CLIENT_PREALLOCATE"] = "false" + + from jax import config + + config.update("jax_enable_x64", True) + + import mlflow + from utils.runner import run + from utils.misc import export_run + + with mlflow.start_run(run_id=run_id) as mlflow_run: + solver_output, postprocessing_output = run(cfg) + mlflow.log_artifact(cfg["models"]["bandwidth"]["file"]) + + export_run(mlflow_run.info.run_id) + + val = solver_output[0][0] + grad = solver_output[1] + + return val, grad + + +if __name__ == "__main__": + import uuid + + logging.basicConfig(filename=f"runlog-tpd-learn-{str(uuid.uuid4())[-4:]}.log", level=logging.INFO) + + # use the logger to note that we're running a parsl job + # logging.info("Running with parsl") + + import jax + from jax.flatten_util import ravel_pytree + + jax.config.update("jax_platform_name", "cpu") + jax.config.update("jax_enable_x64", True) + + import optax + + misc.setup_parsl("gpu", num_gpus=4, max_blocks=8) + run_one_val_and_grad = python_app(run_one_val_and_grad) + + import yaml, mlflow, tempfile, os + import numpy as np, equinox as eqx + from adept.lpse2d import nn + + with open(f"/global/homes/a/archis/adept/configs/envelope-2d/tpd-opt.yaml", "r") as fi: + cfg = yaml.safe_load(fi) + + mlflow.set_experiment(cfg["mlflow"]["experiment"]) + + with mlflow.start_run(run_name="gen-tpd") as mlflow_run: + with tempfile.TemporaryDirectory(dir=BASE_TEMPDIR) as td: + with open(os.path.join(td, "config.yaml"), "w") as fi: + yaml.dump(cfg, fi) + mlflow.log_artifacts(td) + misc.log_params(cfg) + + parent_run_id = mlflow_run.info.run_id + misc.export_run(parent_run_id) + + rng = np.random.default_rng(6367) + + if "hyperparams" in cfg["models"]["bandwidth"]: + weights = nn.GenerativeDriver(**cfg["models"]["bandwidth"]["hyperparams"]) + else: + initial_amps = rng.uniform(0, 1, cfg["drivers"]["E0"]["num_colors"]) + initial_phases = rng.uniform(0, 1, cfg["drivers"]["E0"]["num_colors"]) + weights = {"amps": initial_amps, "phases": initial_phases} + + cfg["mode"] = "optimize-bandwidth" + batch_size = 32 + with mlflow.start_run(run_id=parent_run_id, log_system_metrics=True) as mlflow_run: + opt = optax.adam(learning_rate=cfg["opt"]["learning_rate"]) + opt_state = opt.init(eqx.filter(weights, eqx.is_array)) # initialize the optimizer state + + with tempfile.TemporaryDirectory( + dir=BASE_TEMPDIR + ) as td: # create a temporary directory for optimizer run artifacts + + os.makedirs(os.path.join(td, "weights-history"), exist_ok=True) # create a directory for model history + with open(cfg_path := os.path.join(td, "config.yaml"), "w") as fi: + yaml.dump(cfg, fi) + + for i in range(1000): # 1000 epochs + + if "hyperparams" in cfg["models"]["bandwidth"]: + nn.save( + weights_path := os.path.join(td, "weights-history", f"weights-{i}.eqx"), + cfg["models"]["bandwidth"], + weights, + ) + else: + with open(weights_path := os.path.join(td, "weights-history", f"weights-{i}.pkl"), "wb") as fi: + pickle.dump(weights, fi) + cfg["models"]["bandwidth"]["file"] = weights_path + + if batch_size == 1: + with mlflow.start_run(nested=True, run_name=f"epoch-{i}") as nested_run: + pass + val, avg_grad = run_one_val_and_grad(cfg, run_id=nested_run.info.run_id) + else: + val_and_grads = [] + for j in range(batch_size): + with mlflow.start_run(nested=True, run_name=f"epoch-{i}-sim-{j}") as nested_run: + # val, grad = run_one_val_and_grad(cfg, run_id=nested_run.info.run_id).result() + val_and_grads.append(run_one_val_and_grad(cfg, run_id=nested_run.info.run_id)) + + vgs = [vg.result() for vg in val_and_grads] # get the results of the futures + val = np.mean([v for v, _ in vgs]) # get the mean of the loss values + + avg_grad = misc.all_reduce_gradients( + [g for _, g in vgs], batch_size + ) # get the average of the gradients + + grad_bandwidth = avg_grad["bandwidth"] + flat_grad, _ = ravel_pytree(grad_bandwidth) + mlflow.log_metrics({"grad norm": float(np.linalg.norm(flat_grad))}, step=i) + mlflow.log_metrics({"loss": float(val)}, step=i) + misc.export_run(parent_run_id, prefix="parent", step=i) + updates, opt_state = opt.update(grad_bandwidth, opt_state, weights) + weights = eqx.apply_updates(weights, updates) diff --git a/tpd_sweep.py b/tpd_sweep.py new file mode 100644 index 0000000..872cd21 --- /dev/null +++ b/tpd_sweep.py @@ -0,0 +1,105 @@ +from parsl.app.app import python_app +import logging, os +import equinox as eqx + +logger = logging.getLogger(__name__) + +if "BASE_TEMPDIR" in os.environ: + BASE_TEMPDIR = os.environ["BASE_TEMPDIR"] +else: + BASE_TEMPDIR = None + +from utils import misc + + +def run_once(Te, L, I0, dw, nc): + import os + + os.environ["XLA_PYTHON_CLIENT_PREALLOCATE"] = "false" + + from jax import config + + config.update("jax_enable_x64", True) + # config.update("jax_disable_jit", True) + + import yaml, mlflow + from utils.runner import run + from utils.misc import export_run + + with open("/global/homes/a/archis/adept/configs/envelope-2d/tpd.yaml", "r") as fi: + cfg = yaml.safe_load(fi) + + cfg["mlflow"]["experiment"] = "tpd-8nc-scan" + cfg["density"]["gradient scale length"] = f"{L}um" + cfg["units"]["laser intensity"] = f"{I0:.2e}W/cm^2" + cfg["units"]["reference electron temperature"] = f"{Te}eV" + if dw == 0.0: + cfg["drivers"]["E0"]["num_colors"] = 1 + else: + cfg["drivers"]["E0"]["num_colors"] = nc + + # cfg["drivers"]["E0"]["amplitude_shape"] = _amp_ + cfg["drivers"]["E0"]["delta_omega_max"] = float(dw) + # collisions off + cfg["terms"]["epw"]["damping"]["collisions"] = False + + mlflow.set_experiment(cfg["mlflow"]["experiment"]) + # modify config + with mlflow.start_run( + run_name=f"nonu-Te={Te:.2f}, L={L:.2f}, I0={I0:.2e}, dw={float(dw)}, nc={float(nc)}" + ) as mlflow_run: + result, datasets = run(cfg) + + export_run(mlflow_run.info.run_id) + + +if __name__ == "__main__": + import uuid + from itertools import product + from tqdm import tqdm + import numpy as np + + logging.basicConfig(filename=f"runlog-tpd-learn-{str(uuid.uuid4())[-4:]}.log", level=logging.INFO) + + # use the logger to note that we're running a parsl job + logging.info("Running with parsl") + + import jax + + # from jax.flatten_util import ravel_pytree + + # jax.config.update("jax_platform_name", "cpu") + jax.config.update("jax_enable_x64", True) + + misc.setup_parsl("gpu", 4, 16) + # misc.setup_parsl("local", 4) + run_once = python_app(run_once) + + # create the dataset with the appropriate independent variables + + # 125 simulations in total + Tes = np.linspace(2000, 4000, 3) + Ls = np.linspace(200, 400, 3) + I0s = np.linspace(2, 10, 5)[:, None] * 10 ** np.linspace(13, 16, 4)[None, :] + I0s = I0s.flatten(order="F") + # amp_spec = ["uniform", "mono"] + dws = np.linspace(0.0, 0.03, 3) + ncs = [8, 16, 32] + + all_inputs = list(product(Tes, Ls, I0s, dws, ncs)) + + res = [] + done_runs = [] + for Te, L, I0, dw, nc in all_inputs: + # for I0 in I0s: + if dw == 0.0: + if (Te, L, I0, dw, 1) in done_runs: + continue + else: + res.append(run_once(Te=Te, L=L, I0=I0, dw=dw, nc=nc)) + done_runs.append((Te, L, I0, dw, 1)) + else: + res.append(run_once(Te=Te, L=L, I0=I0, dw=dw, nc=nc)) + + for r in tqdm(res): + print(r.result()) diff --git a/utils/misc.py b/utils/misc.py index 15d9bc4..f84c4f7 100644 --- a/utils/misc.py +++ b/utils/misc.py @@ -5,6 +5,8 @@ from mlflow.tracking import MlflowClient import jax import equinox as eqx + + from mlflow_export_import.run.export_run import RunExporter @@ -149,7 +151,7 @@ def queue_sim(sim_request): return submissionResult -def upload_dir_to_s3(local_directory: str, bucket: str, destination: str, run_id: str): +def upload_dir_to_s3(local_directory: str, bucket: str, destination: str, run_id: str, prefix="individual", step=0): """ Uploads directory to s3 bucket for ingestion into mlflow on remote / cloud side @@ -177,15 +179,87 @@ def upload_dir_to_s3(local_directory: str, bucket: str, destination: str, run_id with open(os.path.join(local_directory, f"ingest-{run_id}.txt"), "w") as fi: fi.write("ready") - client.upload_file(os.path.join(local_directory, f"ingest-{run_id}.txt"), bucket, f"ingest-{run_id}.txt") + if prefix == "individual": + fname = f"ingest-{run_id}.txt" + else: + fname = f"{prefix}-{run_id}-{step}.txt" + + client.upload_file(os.path.join(local_directory, f"ingest-{run_id}.txt"), bucket, fname) -def export_run(run_id): +def export_run(run_id, prefix="individual", step=0): t0 = time.time() run_exp = RunExporter(mlflow_client=mlflow.MlflowClient()) with tempfile.TemporaryDirectory() as td2: run_exp.export_run(run_id, td2) - print(f"Export took {round(time.time() - t0, 2)} s") + # print(f"Export took {round(time.time() - t0, 2)} s") t0 = time.time() - upload_dir_to_s3(td2, "remote-mlflow-staging", f"artifacts/{run_id}", run_id) - print(f"Uploading took {round(time.time() - t0, 2)} s") + upload_dir_to_s3(td2, "remote-mlflow-staging", f"artifacts/{run_id}", run_id, prefix, step) + # print(f"Uploading took {round(time.time() - t0, 2)} s") + + +def setup_parsl(parsl_provider="local", num_gpus=4, max_blocks=3): + import parsl + from parsl.config import Config + from parsl.providers import SlurmProvider, LocalProvider + from parsl.launchers import SrunLauncher + from parsl.executors import HighThroughputExecutor + + if parsl_provider == "local": + + print(f"Using local provider, ignoring {max_blocks=}") + + this_provider = LocalProvider + provider_args = dict( + worker_init="source /pscratch/sd/a/archis/venvs/adept-gpu/bin/activate; \ + module load cudnn/8.9.3_cuda12.lua; \ + export PYTHONPATH='$PYTHONPATH:/global/homes/a/archis/adept/'; \ + export BASE_TEMPDIR='/pscratch/sd/a/archis/tmp/'; \ + export MLFLOW_TRACKING_URI='/pscratch/sd/a/archis/mlflow'; \ + export JAX_ENABLE_X64=True;\ + export MLFLOW_EXPORT=True", + init_blocks=1, + max_blocks=1, + ) + + htex = HighThroughputExecutor( + available_accelerators=num_gpus, + label="tpd-sweep", + provider=this_provider(**provider_args), + cpu_affinity="block", + ) + print(f"{htex.workers_per_node=}") + + elif parsl_provider == "gpu": + + this_provider = SlurmProvider + sched_args = ["#SBATCH -C gpu&hbm80g", "#SBATCH --qos=regular"] + provider_args = dict( + partition=None, + account="m4490_g", + scheduler_options="\n".join(sched_args), + worker_init="export SLURM_CPU_BIND='cores';\ + source /pscratch/sd/a/archis/venvs/adept-gpu/bin/activate; \ + module load cudnn/8.9.3_cuda12.lua; \ + export PYTHONPATH='$PYTHONPATH:/global/homes/a/archis/adept/'; \ + export BASE_TEMPDIR='/pscratch/sd/a/archis/tmp/'; \ + export MLFLOW_TRACKING_URI='/pscratch/sd/a/archis/mlflow';\ + export JAX_ENABLE_X64=True;\ + export MLFLOW_EXPORT=True", + launcher=SrunLauncher(overrides="--gpus-per-node 4 -c 128"), + walltime="1:00:00", + cmd_timeout=120, + nodes_per_block=1, + # init_blocks=1, + max_blocks=max_blocks, + ) + + htex = HighThroughputExecutor( + available_accelerators=4, label="tpd-learn", provider=this_provider(**provider_args), cpu_affinity="block" + ) + print(f"{htex.workers_per_node=}") + + config = Config(executors=[htex], retries=4) + + # load the Parsl config + parsl.load(config) diff --git a/utils/runner.py b/utils/runner.py index 1c67716..44467f3 100644 --- a/utils/runner.py +++ b/utils/runner.py @@ -2,10 +2,8 @@ import os, time, tempfile, yaml -from diffrax import diffeqsolve, SaveAt, Solution -import numpy as np -import equinox as eqx -import mlflow, pint, jax +from diffrax import Solution +import mlflow, jax from utils import misc @@ -16,20 +14,20 @@ BASE_TEMPDIR = None -def get_helpers(mode): - if mode == "tf-1d": +def get_helpers(solver): + if solver == "tf-1d": from adept.tf1d import helpers - elif mode == "sh-2d": + elif solver == "sh-2d": from adept.sh2d import helpers - elif mode == "vlasov-1d": + elif solver == "vlasov-1d": from adept.vlasov1d import helpers - elif mode == "vlasov-1d2v": + elif solver == "vlasov-1d2v": from adept.vlasov1d2v import helpers - elif mode == "vlasov-2d": + elif solver == "vlasov-2d": from adept.vlasov2d import helpers - elif mode == "envelope-2d": + elif solver == "envelope-2d": from adept.lpse2d import helpers - elif mode == "vfp-2d": + elif solver == "vfp-2d": from adept.vfp1d import helpers else: raise NotImplementedError("This solver approach has not been implemented yet") @@ -58,7 +56,7 @@ def run(cfg: Dict) -> Tuple[Solution, Dict]: """ t__ = time.time() # starts the timer - helpers = get_helpers(cfg["mode"]) # gets the right helper functions depending on the desired simulation + helpers = get_helpers(cfg["solver"]) # gets the right helper functions depending on the desired simulation with tempfile.TemporaryDirectory(dir=BASE_TEMPDIR) as td: with open(os.path.join(td, "config.yaml"), "w") as fi: @@ -73,69 +71,47 @@ def run(cfg: Dict) -> Tuple[Solution, Dict]: # NB - this is solver specific cfg["grid"] = helpers.get_solver_quantities(cfg) # gets the solver quantities from the configuration - cfg = helpers.get_save_quantities(cfg) # gets the save quantities from the configuration # create the dictionary of time quantities that is given to the time integrator and save manager tqs = { - "t0": cfg["grid"]["tmin"], + "t0": 0.0, "t1": cfg["grid"]["tmax"], "max_steps": cfg["grid"]["max_steps"], - "save_t0": cfg["grid"]["tmin"], + "save_t0": 0.0, # cfg["grid"]["tmin"], "save_t1": cfg["grid"]["tmax"], "save_nt": cfg["grid"]["tmax"], } # in case you are using ML models - models = helpers.get_models(cfg["models"]) if "models" in cfg else None + models = helpers.get_models(cfg["models"]) if "models" in cfg else {} # initialize the state for the solver - NB - this is solver specific - state = helpers.init_state(cfg, td) - - # NB - this is solver specific - # Remember that we rely on the diffrax library to provide the ODE (time, usually) integrator - # So we need to create the diffrax terms, solver, and save objects - diffeqsolve_quants = helpers.get_diffeqsolve_quants(cfg) + state, args = helpers.init_state(cfg, td) # run t0 = time.time() + _run_ = helpers.get_run_fn(cfg) - @eqx.filter_jit - def _run_(these_models, time_quantities: Dict): - args = {"drivers": cfg["drivers"]} - if these_models is not None: - args["models"] = these_models - if "terms" in cfg.keys(): - args["terms"] = cfg["terms"] - - return diffeqsolve( - terms=diffeqsolve_quants["terms"], - solver=diffeqsolve_quants["solver"], - t0=time_quantities["t0"], - t1=time_quantities["t1"], - max_steps=cfg["grid"]["max_steps"], # time_quantities["max_steps"], - dt0=cfg["grid"]["dt"], - y0=state, - args=args, - saveat=SaveAt(**diffeqsolve_quants["saveat"]), - ) - - _log_flops_(_run_, models, tqs) - result = _run_(models, tqs) + try: + _log_flops_(_run_, models, state, args, tqs) + except: + print("Flops not logged") + run_output = _run_(models, state, args, tqs) mlflow.log_metrics({"run_time": round(time.time() - t0, 4)}) # logs the run time to mlflow t0 = time.time() # NB - this is solver specific - datasets = helpers.post_process(result, cfg, td) # post-processes the result + post_processing_output = helpers.post_process(run_output, cfg, td, args) # post-processes the result mlflow.log_metrics({"postprocess_time": round(time.time() - t0, 4)}) # logs the post-process time to mlflow mlflow.log_artifacts(td) # logs the temporary directory to mlflow mlflow.log_metrics({"total_time": round(time.time() - t__, 4)}) # logs the total time to mlflow # fin - return result, datasets + return run_output, post_processing_output -def _log_flops_(_run_, models, tqs): +def _log_flops_(_run_, models, state, args, tqs): """ Logs the number of flops to mlflow @@ -146,7 +122,7 @@ def _log_flops_(_run_, models, tqs): """ wrapped = jax.xla_computation(_run_) - computation = wrapped(models, tqs) + computation = wrapped(models, state, args, tqs) module = computation.as_hlo_module() client = jax.lib.xla_bridge.get_backend() analysis = jax.lib.xla_client._xla.hlo_module_cost_analysis(client, module)