def main(): # -- DEFINE SIMULATION PARAMETERS x_min = 0. x_max = 2. Nx = 512 t_min = 0. t_max = 6.0 Nt = 30000 n_skip = 10 delta = 0.022 # -- INITIALIZATION STAGE # ... COMPUTATIONAL DOMAIN x = np.linspace(x_min, x_max, Nx, endpoint=False) k = FTFREQ(x.size, d=x[1] - x[0]) * 2 * np.pi # ... KORTEWEG DEVRIES MODEL Lk = -1j * k * k * k * delta * delta Nk_fun = lambda uk: 0.5j * k * FT(IFT(uk)**2) # ... SOLVER BASED ON INTEGRATING FACTOR METHOD solver = IFM_RK4IP(Lk, Nk_fun) # ... INITIAL CONDITION u_0x = np.cos(np.pi * x) solver.set_initial_condition(k, FT(u_0x)) # -- RUN SIMULATION solver.propagate(z_range=t_max, n_steps=Nt, n_skip=n_skip) plot_evolution_KdV(solver.z, x, np.real(solver.utz))
def main(): # -- DEFINE SIMULATION PARAMETERS x_max, Nx = np.pi, 512 t_max, Nt = 30.0, 60000 n_skip = 60 P, theta, d2 = 1.37225, 2., -0.002 # -- INITIALIZATION STAGE # ... COMPUTATIONAL DOMAIN x = np.linspace(-x_max, x_max, Nx, endpoint=False) k = FTFREQ(x.size, d=x[1] - x[0]) * 2 * np.pi # ... LUGIATO-LEFEVER MODEL Lk = lambda k: -(1 + 1j * theta) + 1j * d2 * k * k Nk = lambda uk: (lambda ut: (FT(1j * np.abs(ut)**2 * ut + P)))(IFT(uk)) # ... SOLVER BASED ON SIMPLE SPLIT-STEP FOURIER METHOD solver = SiSSM(Lk(k), Nk) # ... INITIAL CONDITION u_0k = FT(0.5 + np.exp(-(x / 0.85)**2) + 0j) solver.set_initial_condition(k, u_0k) # -- RUN SIMULATION solver.propagate(z_range=t_max, n_steps=Nt, n_skip=n_skip) t_, uxt = solver.z, solver.utz x_lim = (-np.pi, np.pi) k_lim = (-150, 150) plot_evolution_LLE(t_, x, uxt, x_lim, k_lim)
def determine_error(mode): # -- SET AXES grid = Grid(t_max=50., t_num=2**12) t, w = grid.t, grid.w # -- INITIALIZATION STAGE # ... SET MODEL b2 = -1. gamma = 1. model = NSE(w, b2, gamma) # ... SET SOLVER TYPE switcher = { 'SiSSM': SiSSM(model.Lw, model.Nw), 'SySSM': SySSM(model.Lw, model.Nw), 'IFM': IFM_RK4IP(model.Lw, model.Nw), 'LEM': LEM_SySSM(model.Lw, model.Nw), 'CQE': CQE(model.Lw, model.Nw, del_G=1e-6) } try: my_solver = switcher[mode] except KeyError: print('NOTE: MODE MUST BE ONE OF', list(switcher.keys())) raise exit() # -- AVERAGE RELATIVE INTENSITY ERROR _RI_error = lambda x, y: np.sum( np.abs(np.abs(x)**2 - np.abs(y)**2) / x.size / np.max(np.abs(y)**2)) # -- SET TEST PULSE PROPERTIES (FUNDAMENTAL SOLITON) t0 = 1. # duration P0 = np.abs(b2) / t0 / t0 / gamma # peak-intensity LD = t0 * t0 / np.abs(b2) # dispersion length # ... EXACT SOLUTION u_exact = lambda z, t: np.sqrt(P0) * np.exp(0.5j * gamma * P0 * z ) / np.cosh(t / t0) # ... INITIAL CONDITION FOR PROPAGATION u0_t = u_exact(0.0, t) res_dz = [] res_err = [] for z_num in [2**n for n in range(5, 12)]: # ... PROPAGATE INITIAL CONITION my_solver.set_initial_condition(w, FT(u0_t)) my_solver.propagate(z_range=0.5 * np.pi * LD, n_steps=z_num, n_skip=8) # ... KEEP RESULTS z_fin = my_solver.z[-1] dz = z_fin / (z_num + 1) u_t_fin = my_solver.utz[-1] u_t_fin_exact = u_exact(z_fin, t) res_dz.append(dz) res_err.append(_RI_error(u_t_fin, u_t_fin_exact)) # ... CLEAR DATA FIELDS my_solver.clear() return np.asarray(res_dz), np.asarray(res_err)
def main(): # -- SET MODEL PARAMETERS t_max = -50.0 Nt = 2**12 # ... PROPAGATION CONSTANT (POLYNOMIAL MODEL) beta = np.poly1d([-0.5, 0.0, 0.0]) beta1 = np.polyder(beta, m=1) beta2 = np.polyder(beta, m=2) # ... NONLINEAR PARAMETER gamma = 1.0 # ... SOLITON PARAMTERS t0 = 1.0 # duration t_off = 20.0 # temporal offset w0 = 25.0 # detuning P0 = np.abs(beta2(0)) / t0 / t0 / gamma # peak-intensity LD = t0 * t0 / np.abs(beta2(0)) # dispersion length # ... EXACT SOLUTION u_exact = lambda z, t: np.sqrt(P0) * np.exp(0.5j * gamma * P0 * z ) / np.cosh(t / t0) # -- INITIALIZATION STAGE # ... COMPUTATIONAL DOMAIN grid = Grid(t_max=t_max, t_num=Nt) t, w = grid.t, grid.w # ... NONLINEAR SCHROEDINGER EQUATION model = NSE(w, beta(w), gamma) # ... PROPAGATION ALGORITHM solver = LEM(model.Lw, model.N, del_G=1e-7) # ... INITIAL CONDITION u0_t = u_exact(0.0, t + t_off) * np.exp(1j * w0 * t) u0_t += u_exact(0.0, t - t_off) * np.exp(-1j * w0 * t) solver.set_initial_condition(w, FT(u0_t)) # -- RUN SOLVER solver.propagate( z_range=0.5 * np.pi * LD, n_steps=2**9, n_skip=2 # propagation range ) # -- STORE RESULTS # ... PREPARE DATA DICTIONARY FOR OUTPUT FILE results = { "t": t, "z": solver.z, "w": solver.w, "u": solver.utz, "dz_integration": solver.dz_, "dz_a": np.asarray(solver._dz_a), "del_rle": np.asarray(solver._del_rle), } # ... STORE DATA save_h5("./res_LEM_SolSolCollision.h5", **results)
def main(): # -- DEFINE SIMULATION PARAMETERS # ... WAVEGUIDE PROPERTIES b2 = -1.0 gamma = 1. # ... TEST PULSE PROPERTIES t0 = 1. # soliton duration P0 = np.abs(b2) / t0 / t0 / gamma # peak-intensity LD = t0 * t0 / np.abs(b2) # dispersion length N_sol = 3 # soliton order # ... COMPUTATIONAL DOMAIN t_max = 30. t_num = 2**12 z_max = 0.5 * np.pi * LD z_num = 1000 z_skip = 2 # -- INITIALIZATION STAGE # ... COMPUTATIONAL DOMAIN grid = Grid(t_max=t_max, t_num=t_num, z_max=z_max, z_num=z_num) # ... NSE MODEL model = NSE(grid.w, b2, gamma) # ... Z-PROPAGATION USING SYMMETRIC SPLIT-STEP FOURIER METHOD solver = SySSM(model.Lw, model.Nw) # ... INITIAL CONDITION u_0t = N_sol * np.sqrt(P0) / np.cosh(grid.t / t0) solver.set_initial_condition(grid.w, FT(u_0t)) # -- RUN SIMULATION solver.propagate(z_range=z_max, n_steps=z_num, n_skip=z_skip) plot_evolution(solver.z, grid.t, solver.utz, t_lim=(-4, 4), w_lim=(-50, 50), DO_T_LOG=False)
def plot_evolution_LLE(z, t, u, t_lim, w_lim): def _setColorbar(im, refPos): """colorbar helper""" x0, y0, w, h = refPos.x0, refPos.y0, refPos.width, refPos.height cax = f.add_axes([x0, y0 + 1.02 * h, w, 0.03 * h]) cbar = f.colorbar(im, cax=cax, orientation='horizontal') cbar.ax.tick_params(color='k', labelcolor='k', bottom=False, direction='out', labelbottom=False, labeltop=True, top=True, size=4, pad=0) cbar.ax.tick_params(which="minor", bottom=False, top=False) return cbar w = FTSHIFT(FTFREQ(t.size, d=t[1] - t[0]) * 2 * np.pi) f, (ax1, ax2) = plt.subplots(1, 2, sharey=True, figsize=(8, 4)) plt.subplots_adjust(left=0.13, right=0.96, bottom=0.12, top=0.8, wspace=0.05) cmap = mpl.cm.get_cmap('jet') # -- LEFT SUB-FIGURE: TIME-DOMAIN PROPAGATION CHARACTERISTICS It = np.abs(u)**2 It /= np.max(It) my_norm = col.Normalize(vmin=0, vmax=1) im1 = ax1.pcolorfast(t, z, It[:-1, :-1], norm=my_norm, cmap=cmap) cbar1 = _setColorbar(im1, ax1.get_position()) cbar1.ax.set_title(r"$|u|^2/{\rm{max}}\left(|u|^2\right)$", color='k', y=3.5) ax1.set_xlim(t_lim) ax1.set_ylim([0., z.max()]) ax1.set_xlabel(r"$x$") ax1.set_ylabel(r"$t$") ax1.ticklabel_format(useOffset=False, style='plain') # -- RIGHT SUB-FIGURE: ANGULAR FREQUENCY-DOMAIN PROPAGATION CHARACTERISTICS Iw = np.abs(FTSHIFT(FT(u, axis=-1), axes=-1))**2 Iw /= np.max(Iw) im2 = ax2.pcolorfast(w, z, Iw[:-1, :-1], norm=col.LogNorm(vmin=1e-6 * Iw.max(), vmax=Iw.max()), cmap=cmap) cbar2 = _setColorbar(im2, ax2.get_position()) cbar2.ax.set_title(r"$|u_k|^2/{\rm{max}}\left(|u_k|^2\right)$", color='k', y=3.5) ax2.set_xlim(w_lim) ax2.set_ylim([0., z.max()]) ax2.set_xlabel(r"$k$") ax2.tick_params(labelleft=False) ax2.ticklabel_format(useOffset=False, style='plain') plt.show()
def N(self, uw): ut = IFT(uw) return 1j * self.gamma * FT(np.abs(ut)**2 * ut)
def Nw(self, uw): ut = IFT(uw) return self._de_alias(1j * self.gamma * FT(np.abs(ut)**2 * ut))
############################################################################### # Next, we initialize the computational domain and use a symmetric split-step # Fourier method to propagate a single third-order soliton for six soliton # periods. # For this numerical experiment, the extend of the time domain and the number # of sample points is chosen large enough to allow for a zero padding # anti-aliasing technique without cropping important parts of the spectrum. grid = Grid(t_max=34., t_num=2**12) t, w = grid.t, grid.w model = NSE(w, b2=-1., gamma=1.) u_0t = 4. / np.cosh(t) solver = SySSM(model.Lw, model.Nw) solver.set_initial_condition(w, FT(u_0t)) solver.propagate(z_range=3 * np.pi / 2, n_steps=10000, n_skip=50) z, utz = solver.z_, solver.utz plot_evolution(solver.z, grid.t, solver.utz, t_lim=(-5, 5), w_lim=(-60, 60), DO_T_LOG=False) ############################################################################### # **References:** # # .. [B2001] J.P. Boyd, Chebychev and Fourier Spectral Methods, Dover, New York (2001) #
def Ce(i, zi, w, uw): return np.sum(np.abs(uw)**2) # -- INITIALIZATION STAGE # ... COMPUTATIONAL DOMAIN grid = Grid(t_max=t_max, t_num=Nt) t, w = grid.t, grid.w model = NSE(w, beta(w), alpha, gamma) # ... PROPAGATION ALGORITHM solver = SySSM(model.Lw, model.N, user_action=Ce) # ... INITIAL CONDITION solver.set_initial_condition(w, FT(u_exact(0.0, t))) # -- RUN SOLVER solver.propagate(z_range=0.5 * np.pi * LD, n_steps=512, n_skip=2) # propagation range ############################################################################### # In the figure below, the top subfigure shows the time-domain propagation # dynamics of a fundamental soliton for the nonlinear Schrödinger equation in # the presence of fiber loss. # The subfigure at the bottom show the resulting decay of the energy in the # numerical experiment (solid line), along with the theoretical prediction # (dashed line). import matplotlib as mpl import matplotlib.pyplot as plt
def determine_error(mode, stepper): # -- SET MODEL PARAMETERS # ... PROPAGATION CONSTANT (POLYNOMIAL MODEL) beta = np.poly1d([-0.5, 0.0, 0.0]) # ... GROUP VELOCITY beta1 = np.polyder(beta, m=1) # ... GROUP VELOCITY DISPERSION beta2 = np.polyder(beta, m=2) # ... NONLINEAR PARAMETER gamma = 1. # -- SET AXES t_max, t_num = 50., 2**12 t = np.linspace(-t_max, t_max, t_num, endpoint=False) w = nfft.fftfreq(t.size, d=t[1] - t[0]) * 2 * np.pi # -- INITIALIZE SOLVER # ... SET MODEL model = NSE(w, -1.0, gamma) #model = NSE(w, beta(w), gamma) # ... SET Z-STEPPER switcher = {'RK2': RungeKutta2, 'RK4': RungeKutta4} try: my_stepper = switcher[stepper] except KeyError: print('NOTE: STEPPER MUST BE ONE OF', list(switcher.keys())) raise exit() # ... SET SOLVER TYPE switcher = { 'SiSSM': SiSSM(model.Lw, model.Nw, my_stepper), 'SySSM': SySSM(model.Lw, model.Nw, my_stepper), 'IFM': IFM_RK4IP(model.Lw, model.Nw), 'LEM': LEM_SySSM(model.Lw, model.Nw, my_stepper), 'CQE': CQE(model.Lw, model.Nw, del_G=1e-6), 'MLEM': LEM_IFM(model.Lw, model.Nw) } try: my_solver = switcher[mode] except KeyError: print('NOTE: MODE MUST BE ONE OF', list(switcher.keys())) raise exit() # -- FUNCTIONS FOR ERROR ESTIMATION # ... AVERAGE RMS ERROR, REF. [DeVries, AIP Conference Proceedings 160, 269 (1987)] _RMS_error = lambda x, y: np.sqrt(np.sum(np.abs(x - y)**2) / x.size) # ... AVERAGE RELATIVE INTENSITY ERROR, REF. [Hult, J. Lightwave Tech., 25, 3770 (2007)] _RI_error = lambda x, y: np.sum( np.abs(np.abs(x)**2 - np.abs(y)**2) / x.size / np.max(np.abs(y)**2)) # -- SET TEST PULSE PROPERTIES (FUNDAMENTAL SOLITON) t0 = 1. # duration P0 = np.abs(beta2(0)) / t0 / t0 / gamma # peak-intensity LD = t0 * t0 / np.abs(beta2(0)) # dispersion length # ... EXACT SOLUTION u_exact = lambda z, t: np.sqrt(P0) * np.exp(0.5j * gamma * P0 * z ) / np.cosh(t / t0) # ... INITIAL CONDITION FOR PROPAGATION u0_t = u_exact(0.0, t) # -- SET PROPAGATION RANGE z_max = 0.5 * np.pi * LD # propagate for one soliton period z_skip = 8 # number of system states to skip data = dict() for z_num in [2**n for n in range(4, 15)]: # ... PROPAGATE INITIAL CONITION my_solver.set_initial_condition(w, FT(u0_t)) my_solver.propagate(z_range=z_max, n_steps=z_num, n_skip=z_skip) dz = z_max / (z_num + 1) z_fin = my_solver.z[-1] u_t_fin = my_solver.utz[-1] u_t_fin_exact = u_exact(z_fin, t) # ... KEEP RESULTS data[dz] = (z_fin, z_num, _RMS_error(u_t_fin, u_t_fin_exact), _RI_error(u_t_fin, u_t_fin_exact)) # ... CLEAR DATA FIELDS my_solver.clear() return data
# -- INITIALIZATION STAGE # ... COMPUTATIONAL DOMAIN grid = Grid( t_max = 30., t_num = 2**10) t, w = grid.t, grid.w # ... NSE MODEL model = NSE(w, b2=-1., gamma=1.) # ... INITIAL CONDITION u_0t = 1./np.cosh(t) ############################################################################### # In a first numerical experiment, the stepsize is intentionally kept very # large in order to allow the numerical istabilities to build up. solver = SySSM(model.Lw, model.Nw) solver.set_initial_condition(w, FT(u_0t)) solver.propagate(z_range = 10*np.pi, n_steps = 511, n_skip = 1) z, utz = solver.z_, solver.utz ############################################################################### # In this case, instabilities are expected to build up since the # :math:`z`-increment :math:`\Delta z`, used by the propagation algorithm, # exceeds the threshold increment :math:`\Delta # z_{\mathrm{T}}=2\pi/\mathrm{max}(\omega)` (both increments are displayed # below). # -- MAXIMUM FREQUENCY SUPPORTED ON COMPUTATIONAL GRID w_max = np.pi/(t[1]-t[0]) # -- THRESHOLD INCREMENT dz_T = np.pi*2/w_max**2