def construct_A(kicks): # A = np.zeros((len(kicks), len(kicks)), dtype = np.complex128) A = np.tri(len(kicks), dtype=np.complex128) # A = sparse.csr_matrix((len(kicks), len(kicks)), dtype = np.complex128) print("size of A", si.utils.bytes_to_str(A.nbytes)) omega = ion.HydrogenBoundState(1, 0).energy / hbar prefactor = ide.hydrogen_prefactor_LEN(electron_charge) def kernel(td): return ide.hydrogen_kernel_LEN(td) * np.exp(1j * omega * td) # tds = np.linspace(0, kicks[-1].time + (100 * asec), num = 1000) # kinterp = interp.interp1d(tds, kernel(tds), kind = 'cubic', fill_value = 0, bounds_error = False, assume_sorted = True) # kernel = lambda td: ide.hydrogen_kernel_LEN(td) * np.exp(1j * omega * td) # time_delays = {(n, m): kicks[n].time - kicks[m].time for n in range(len(kicks)) for m in range(n + 1)} # kernel_dict = {(n, m): kernel(time_delays[n, m]) for n in range(len(kicks)) for m in range(n + 1)} times = np.array([kick.time for kick in kicks]) amplitudes = np.array([kick.amplitude for kick in kicks]) # def element(n, m): # rv = prefactor * amplitudes[n] * amplitudes[m] * kernel(time_delays[n, m]) # if m == n: # rv -= 1 # elif m == n - 1: # first subdiagonal # rv += 1 # # return rv # # with si.utils.BlockTimer() as timer: # for n in range(len(kicks)): # for m in range(n + 1): # A[n, m] = element(n, m) for idx in range(len(kicks)): A[idx, :] *= amplitudes[idx] # row idx A[:, idx] *= amplitudes[idx] # column idx A[idx, :idx + 1] *= kernel(times[idx] - times[:idx + 1]) # A[idx, :] *= kinterp(times[idx] - times) A *= prefactor A[np.arange(len(kicks)), np.arange(len(kicks))] -= 1 # diagonal A[np.arange(len(kicks) - 1) + 1, np.arange(len(kicks) - 1)] += 1 # first subdiagonal A = sparse.csr_matrix(A, dtype=np.complex128) print("size of A", si.utils.bytes_to_str(A.data.nbytes)) return A
def rk4(pulse, tb=3, dts=(1 * asec, 0.1 * asec), processes=2): specs = [ ide.IntegroDifferentialEquationSpecification( f"rk4solver_dt={dt / asec:3f}as__pw={pulse.pulse_width / asec:.3f}as", time_initial=-pulse.pulse_width * tb, time_final=pulse.pulse_width * tb, time_step=dt, electric_potential=pulse, electric_potential_dc_correction=False, kernel=ide.hydrogen_kernel_LEN, integral_prefactor=ide.hydrogen_prefactor_LEN(electron_charge), ) for dt in dts ] return si.utils.multi_map(run, specs, processes=processes)
def run_hyd_ide_sim(pulse, tb, dt=1 * asec): print("IDE", f"{dt / asec:3f}") sim = ide.IntegroDifferentialEquationSpecification( "idesim", electric_potential=pulse, kernel=ide.hydrogen_kernel_LEN, integral_prefactor=ide.hydrogen_prefactor_LEN(electron_charge), time_initial=-pulse.pulse_width * tb, time_final=pulse.pulse_width * tb, time_step=dt, ).to_sim() sim.run() return sim
def solve_ide_implicit_from_kicks_v2(kicks): b = np.empty(len(kicks), dtype=np.complex128) b[0] = 1 omega = ion.HydrogenBoundState(1, 0).energy / hbar prefactor = ide.hydrogen_prefactor_LEN(electron_charge) def kernel(td): return ide.hydrogen_kernel_LEN(td) * np.exp(1j * omega * td) times = np.array([kick.time for kick in kicks]) amplitudes = np.array([kick.amplitude for kick in kicks]) k0 = kernel(0) for n in range(1, len(b)): a_n = amplitudes[n] sum_pre = prefactor * a_n t_n = times[n] s = sum_pre * np.sum( amplitudes[:n] * kernel(times[n] - times[:n]) * b[:n]) b[n] = (b[n - 1] + s) / (1 - (prefactor * k0 * a_n * a_n)) return b, kicks
time_final=pulse.pulse_width * 10, time_step=0.1 * asec, electric_potential=pulse, electric_potential_dc_correction=True, ) specs = [ ide.IntegroDifferentialEquationSpecification( "gaussian", kernel=ide.gaussian_kernel_LEN, kernel_kwargs={ "tau_alpha": ide.gaussian_tau_alpha_LEN(test_width, test_mass) }, integral_prefactor=ide.gaussian_prefactor_LEN( test_width, test_charge), **shared_kwargs, ), ide.IntegroDifferentialEquationSpecification( "hydrogen", kernel=ide.hydrogen_kernel_LEN, kernel_kwargs={ "kernel_prefactor": ide.hydrogen_kernel_prefactor_LEN() }, integral_prefactor=ide.hydrogen_prefactor_LEN(test_charge), **shared_kwargs, ), ] results = si.utils.multi_map(run, specs, processes=2)