def driven_dynamics(ham, dip, psi0, pulse, dt=0.001, Nt=1, e_ops=None, nout=1, \ t0=0.0): ''' Laser-driven dynamics in the presence of laser pulses Parameters ---------- ham : 2d array Hamiltonian of the molecule dip : TYPE transition dipole moment psi0: 1d array initial wavefunction pulse : TYPE laser pulse dt : TYPE time step. Nt : TYPE timesteps. e_ops: list observable operators to compute nout: int Store data every nout steps Returns ------- None. ''' # initialize the density matrix # wf = csr_matrix(wf0).transpose() psi = psi0 nstates = len(psi0) # f = open(fname,'w') fmt = '{} ' * (len(e_ops) + 1) + '\n' fmt_dm = '{} ' * (nstates + 1) + '\n' f_dm = open('psi.dat', 'w') # wavefunction f_obs = open('obs.dat', 'w') # observables t = t0 # f_dip = open('dipole'+'{:f}'.format(pulse.delay * au2fs)+'.dat', 'w') for k1 in range(int(Nt / nout)): for k2 in range(nout): ht = pulse.field(t) * dip + ham psi = rk4(psi, tdse, dt, ht) t += dt * nout # compute observables Aave = np.zeros(len(e_ops), dtype=complex) for j, A in enumerate(e_ops): Aave[j] = obs(psi, A) f_dm.write(fmt_dm.format(t, *psi)) f_obs.write(fmt.format(t, *Aave)) f_dm.close() f_obs.close() return
def _ode_solver(H, psi0, dt=0.001, Nt=1, e_ops=[], t0=0.0, nout=1, store_states=True, output='obs.dat'): """ Integrate the TDSE for a multilevel system using Scipy. Parameters ---------- e_ops: list of arrays expectation values to compute. H : 2d array Hamiltonian of the molecule psi0: 1d array initial wavefunction dt : float time step. Nt : int timesteps. e_ops: list observable operators to compute nout: int Store data every nout steps Returns ------- None. """ psi = psi0.copy() t_eval = np.arange(Nt // nout) * dt * nout def fun(t, psi): return -1j * H.dot(psi) tf = t0 + Nt * dt t_span = (t0, tf) sol = scipy.integrate.solve_ivp(fun, t_span=t_span, y0=psi, t_eval=t_eval) result = Result(dt=dt, Nt=Nt, psi0=psi0) result.times = sol.t print(sol.nfev) observables = np.zeros((Nt // nout, len(e_ops)), dtype=complex) for i in range(len(t_eval)): psi = sol.y[:, i] observables[i, :] = [obs(psi, e_op) for e_op in e_ops] result.observables = observables # if store_states: # # result = Result(dt=dt, Nt=Nt, psi0=psi0) # # observables = np.zeros((Nt // nout, len(e_ops)), dtype=complex) # psilist = [psi0.copy()] # # # compute observables for t0 # observables[0, :] = [obs(psi, e_op) for e_op in e_ops] # # for k1 in range(1, Nt // nout): # # for k2 in range(nout): # psi = rk4(psi, tdse, dt, H) # # t += dt * nout # # # compute observables # observables[k1, :] = [obs(psi, e_op) for e_op in e_ops] # # f_obs.write(fmt.format(t, *e_list)) # # psilist.append(psi.copy()) # # # f_obs.close() # # result.psilist = psilist # result.observables = observables return result
def _quantum_dynamics(H, psi0, dt=0.001, Nt=1, e_ops=[], t0=0.0, nout=1, store_states=True, output='obs.dat'): """ Quantum dynamics for a multilevel system. Parameters ---------- e_ops: list of arrays expectation values to compute. H : 2d array Hamiltonian of the molecule psi0: 1d array initial wavefunction dt : float time step. Nt : int timesteps. e_ops: list observable operators to compute nout: int Store data every nout steps Returns ------- None. """ psi = psi0 if e_ops is not None: fmt = '{} ' * (len(e_ops) + 1) + '\n' f_obs = open(output, 'w') # observables t = t0 # f_obs.close() if store_states: result = Result(dt=dt, Nt=Nt, psi0=psi0) observables = np.zeros((Nt // nout, len(e_ops)), dtype=complex) psilist = [psi0.copy()] # compute observables for t0 observables[0, :] = [obs(psi, e_op) for e_op in e_ops] for k1 in range(1, Nt // nout): for k2 in range(nout): psi = rk4(psi, tdse, dt, H) t += dt * nout # compute observables observables[k1, :] = [obs(psi, e_op) for e_op in e_ops] # f_obs.write(fmt.format(t, *e_list)) psilist.append(psi.copy()) # f_obs.close() result.psilist = psilist result.observables = observables return result else: # not save states for k1 in range(int(Nt / nout)): for k2 in range(nout): psi = rk4(psi, tdse, dt, H) t += dt * nout # compute observables e_list = [obs(psi, e_op) for e_op in e_ops] f_obs.write(fmt.format(t, *e_list)) f_obs.close() return psi
def driven_dynamics(H, edip, psi0, pulse, dt=0.001, Nt=1, e_ops=None, nout=1, \ t0=0.0, return_result=True): ''' Laser-driven dynamics in the presence of laser pulses Parameters ---------- ham : 2d array Hamiltonian of the molecule dip : TYPE transition dipole moment psi0: 1d array initial wavefunction pulse : TYPE laser pulse dt : TYPE time step. Nt : TYPE timesteps. e_ops: list observable operators to compute nout: int Store data every nout steps Returns ------- None. ''' # initialize the density matrix # wf = csr_matrix(wf0).transpose() psi = psi0.astype(complex) nstates = len(psi0) # f = open(fname,'w') if e_ops is None: e_ops = [] t = t0 # f_dip = open('dipole'+'{:f}'.format(pulse.delay * au2fs)+'.dat', 'w') if return_result: result = Result(dt=dt, Nt=Nt, psi0=psi0) observables = np.zeros((Nt // nout, len(e_ops)), dtype=complex) psilist = [psi0.copy()] # compute observables for t0 observables[0, :] = [obs(psi, e_op) for e_op in e_ops] for k1 in range(1, Nt // nout): for k2 in range(nout): ht = -pulse.field(t) * edip + H psi = rk4(psi, tdse, dt, ht) t += dt * nout # compute observables observables[k1, :] = [obs(psi, e_op) for e_op in e_ops] # f_obs.write(fmt.format(t, *e_list)) psilist.append(psi.copy()) # f_obs.close() result.psilist = psilist result.observables = observables return result else: fmt = '{} ' * (len(e_ops) + 1) + '\n' fmt_dm = '{} ' * (nstates + 1) + '\n' f_dm = open('psi.dat', 'w') # wavefunction f_obs = open('obs.dat', 'w') # observables for k1 in range(int(Nt / nout)): for k2 in range(nout): ht = pulse.field(t) * edip + H psi = rk4(psi, tdse, dt, ht) t += dt * nout # compute observables Aave = np.zeros(len(e_ops), dtype=complex) for j, A in enumerate(e_ops): Aave[j] = obs(psi, A) f_dm.write(fmt_dm.format(t, *psi)) f_obs.write(fmt.format(t, *Aave)) f_dm.close() f_obs.close() return