def test_drude(): from minitn.heom.noise import Drude from minitn.lib.units import Quantity # System e = Quantity(100, 'cm-1').value_in_au v = Quantity(50, 'cm-1').value_in_au # Bath corr2 = Correlation(k_max=1) corr2.symm_coeff = [0.0] # [4.66691921e+01 * 9.24899189e+01] corr2.asymm_coeff = [0.0] # [4.66691921e+01 * -2.35486582e+01] corr2.exp_coeff = [1.0] corr2.delta_coeff = 0.0 # delta_coeff() corr2.print() h = np.array([[e, v], [v, 0]]) op = np.array([[1, 0], [0, -1]]) # Superparameters max_tier = 5 # (number of possble values for each n_k in the extended rho) heom = Hierachy([max_tier], h, op, corr2) phi = np.array([1, 0]) rho_0 = np.tensordot(phi, phi, axes=0) init_rho = heom.gen_extended_rho(rho_0) solver = MultiLayer(init_rho, heom.diff()) # Define the obersevable of interest dat = [] for n, (time, r) in enumerate(solver.propagator( steps=20000, ode_inter=0.1, )): if n % 100 == 0: rho = np.reshape(r, (-1, 4)) for n, _ in enumerate(rho): if n == 0: flat_data = [time] + list(rho[0]) dat.append(flat_data) print('Time: {}; rho: {} {} {} {}'.format(*flat_data)) np.savetxt('test.dat', np.array(dat, dtype=np.complex128)) return np.array(dat)
def test_heom(fname=None): ph_dims = list(np.repeat(model.ph_dims, 2)) n_dims = ph_dims if model.bath_dims is None else ph_dims + model.bath_dims print(n_dims) root = tensor_tree_template(rho_0, n_dims, rank=rank_heom) leaves = root.leaves() h_list = model.heom_h_list(leaves[0], leaves[1], leaves[2:], beta=beta) solver = MultiLayer(root, h_list) solver.ode_method = 'RK45' solver.cmf_steps = solver.max_ode_steps # use constant mean-field solver.ps_method = 'split' #solver.svd_err = 1.0e-10 # Define the obersevable of interest logger = Logger(filename=prefix + fname, level='info').logger logger2 = Logger(filename=prefix + "en_" + fname, level='info').logger for n, (time, r) in enumerate( solver.propagator( steps=count, ode_inter=dt_unit, split=True, )): # renormalized by the trace of rho norm = np.trace(np.reshape(np.reshape(r.array, (4, -1))[:, 0], (2, 2))) r.set_array(r.array / norm) if n % callback_interval == 0: t = Quantity(time).convert_to(unit='fs').value rho = np.reshape(r.array, (4, -1))[:, 0] logger.info("{} {} {} {} {}".format(t, rho[0], rho[1], rho[2], rho[3])) en = np.trace(np.reshape(rho, (2, 2)) @ model.h) logger2.info('{} {}'.format(t, en)) return
def test_uni(): from scipy.integrate import solve_ivp # System e = Quantity(100, 'cm-1').value_in_au v = Quantity(50, 'cm-1').value_in_au h = np.array([[e, v], [v, 0]], dtype='double') phi = np.array([1, 0], dtype='complex') ode_int = 0.1 diff = lambda t, y: (h @ y) * (-1.0j) for n in range(20000): time = ode_int * n solver = solve_ivp( diff, (time, time + ode_int), phi, method='RK23', max_step=ode_int, rtol=1e-8, atol=1e-8 ) phi = solver.y[:, -1] if n % 100 == 0: print('Time: {}; rho: {} {}'.format(time, np.abs(phi[0])**2, np.abs(phi[1])**2))
def test_uni_int(): from scipy.integrate import solve_ivp from scipy.linalg import eigh # System e = Quantity(100, 'cm-1').value_in_au v = Quantity(50, 'cm-1').value_in_au h = np.array([[e, v], [v, 0]], dtype='double') l, u = eigh(h) uc = np.conj(np.transpose(u)) phi = np.array([1, 0], dtype='complex') ode_int = 0.1 data = [] for n in range(20000): time = ode_int * n vec = np.dot(uc, (np.exp(-1.0j * time * l) * np.dot(u, phi))) if n % 100 == 0: data.append([time] + list(np.abs(vec)**2)) np.savetxt('reference.dat', np.array(data, dtype=np.complex128))
def test_mctdh(fname=None): sys_leaf = Leaf(name='sys0') ph_leaves = [] for n, (omega, g) in enumerate(ph_parameters, 1): ph_leaf = Leaf(name='ph{}'.format(n)) ph_leaves.append(ph_leaf) def ph_spf(): t = Tensor(axis=0) t.name = 'spf' + str(hex(id(t)))[-4:] return t graph, root = huffman_tree(ph_leaves, obj_new=ph_spf, n_branch=2) try: graph[root].insert(0, sys_leaf) except KeyError: ph_leaf = root root = Tensor() graph[root] = [sys_leaf, ph_leaf] finally: root.name = 'wfn' root.axis = None stack = [root] while stack: parent = stack.pop() for child in graph[parent]: parent.link_to(parent.order, child, 0) if child in graph: stack.append(child) # Define the detailed parameters for the ML-MCTDH tree h_list = model.wfn_h_list(sys_leaf, ph_leaves) solver = MultiLayer(root, h_list) bond_dict = {} # Leaves for s, i, t, j in root.linkage_visitor(): if t.name.startswith('sys'): bond_dict[(s, i, t, j)] = 2 else: if isinstance(t, Leaf): bond_dict[(s, i, t, j)] = max_tier else: bond_dict[(s, i, t, j)] = rank_wfn solver.autocomplete(bond_dict) # set initial root array init_proj = np.array([[A, 0.0], [B, 0.0]]) / np.sqrt(A**2 + B**2) root_array = Tensor.partial_product(root.array, 0, init_proj, 1) root.set_array(root_array) solver = MultiLayer(root, h_list) solver.ode_method = 'RK45' solver.cmf_steps = solver.max_ode_steps # constant mean-field solver.ps_method = 'split' solver.svd_err = 1.0e-14 # Define the obersevable of interest logger = Logger(filename=prefix + fname, level='info').logger logger2 = Logger(filename=prefix + 'en_' + fname, level='info').logger for n, (time, r) in enumerate( solver.propagator( steps=count, ode_inter=dt_unit, split=True, )): if n % callback_interval == 0: t = Quantity(time).convert_to(unit='fs').value rho = r.partial_env(0, proper=False) logger.info("{} {} {} {} {}".format(t, rho[0, 0], rho[0, 1], rho[1, 0], rho[1, 1])) en = np.trace(rho @ model.h) logger2.info('{} {}'.format(t, en))
from __future__ import absolute_import, division, print_function from builtins import filter, map, range, zip from minitn.heom.corr import Drude from minitn.heom.network import tensor_tree_template from minitn.heom.propagate import MultiLayer from minitn.lib.backend import DTYPE, np from minitn.lib.logging import Logger from minitn.lib.tools import huffman_tree from minitn.lib.units import Quantity from minitn.models.sbm import SBM from minitn.tensor import Leaf, Tensor # System: pure dephasing e = Quantity(5000, 'cm-1').value_in_au v = Quantity(500, 'cm-1').value_in_au max_tier = 20 rank_heom = 10 rank_wfn = 8 beta = None prefix = 'drude_boson_tree_zt_t{}_'.format(max_tier) ph_parameters = [ #(Quantity(400, 'cm-1').value_in_au, Quantity(500, 'cm-1').value_in_au), #(Quantity(800, 'cm-1').value_in_au, Quantity(500, 'cm-1').value_in_au), #(Quantity(1200, 'cm-1').value_in_au, Quantity(500, 'cm-1').value_in_au), (Quantity(1600, 'cm-1').value_in_au, Quantity(500, 'cm-1').value_in_au), ] dof = len(ph_parameters)
# coding: utf-8 from __future__ import absolute_import, division, print_function from builtins import filter, map, range, zip from minitn.heom.network import simple_heom, tensor_train_template from minitn.heom.propagate import MultiLayer from minitn.lib.backend import DTYPE, np from minitn.lib.logging import Logger from minitn.lib.tools import huffman_tree from minitn.lib.units import Quantity from minitn.models.sbm import SBM from minitn.tensor import Leaf, Tensor # System: pure dephasing e = Quantity(5000, 'cm-1').value_in_au v = Quantity(500, 'cm-1').value_in_au dof = 1 max_tier = 12 rank_heom = 1 rank_wfn = 8 prefix = '{}-DOF_2site_t{}_'.format(dof, max_tier) ph_parameters = [ #(Quantity(250, 'cm-1').value_in_au, Quantity(500, 'cm-1').value_in_au), (Quantity(750, 'cm-1').value_in_au, Quantity(500, 'cm-1').value_in_au), ] model = SBM( sys_ham=np.array([[-0.5 * e, v], [v, 0.5 * e]], dtype=DTYPE), sys_op=np.array([[-0.5, 0.0], [0.0, 0.5]], dtype=DTYPE),
def sbm_ft(including_bath=False, snd=False): # Define parameters of the model. sbm = SpinBosonModel( including_bath=including_bath, e1=0., e2=Quantity(6500, 'cm-1').value_in_au, v=Quantity(500, 'cm-1').value_in_au, omega_list=[Quantity(2100, 'cm-1').value_in_au], lambda_list=([Quantity(750, 'cm-1').value_in_au]), dim_list=[10], stop=Quantity(10000, 'cm-1').value_in_au, n=32, dim=30, lambda_g=Quantity(2250, 'cm-1').value_in_au, omega_g=Quantity(500, 'cm-1').value_in_au, lambda_d=Quantity(1250, 'cm-1').value_in_au, omega_d=Quantity(50, 'cm-1').value_in_au, mu=Quantity(250, 'cm-1').value_in_au, tau=Quantity(3, 'fs').value_in_au, t_d=Quantity(6, 'fs').value_in_au, omega=Quantity(13000, 'cm-1').value_in_au, ) # Define the topological structure of the ML-MCTDH tree graph, root = { 'ROOT': ['ELECs', 'I0s'], 'ELECs': ['ELEC', "ELEC'"], 'I0s': ['I0', "I0'"], }, 'ROOT' root = Tensor.generate(graph, root) # Define the detailed parameters for the MC-MCTDH tree solver = MultiLayer(root, sbm.h_list, f_list=sbm.f_list, use_str_name=True) bond_dict = {} # Leaves for s, i, t, j in root.linkage_visitor(): if isinstance(t, Leaf): try: dim = sbm.dimensions[t.name] except KeyError: dim = sbm.dimensions[t.name[:-1]] bond_dict[(s, i, t, j)] = dim s_ax = s.axis p, p_ax = s[s_ax] bond_dict[(p, p_ax, s, s_ax)] = dim**2 if dim < 9 else 50 solver.autocomplete(bond_dict, max_entangled=True) # Define the computation details solver.settings(cmf_steps=10, ode_method='RK45', ps_method='split-unite', snd_order=snd) logging.info("Size of a wfn: {} complexes".format(len(root.vectorize()))) # Do the imaginary time propogation inv_tem = 1 / 1000 steps = 100 for time, _ in solver.propagator( steps=steps, ode_inter=Quantity(inv_tem / steps / 2, unit='K-1').value_in_au, split=True, imaginary=True): t = 2 * Quantity(time).convert_to(unit='K-1').value z = solver.relative_partition_function kelvin = 'inf' if abs(t) < 1.e-14 else 1.0 / t logging.warning('Temperatue: {} K; ln(Z/Z_0): {}'.format( kelvin, np.log(z))) # Define the obersevable of interest projector = np.array([[0., 0.], [0., 1.]]) op = [[[root[0][0][1][0], projector]]] # Do the real time propogation tp_list = [] steps = 100 root.is_normalized = True for time, _ in solver.propagator(steps=steps, ode_inter=Quantity(10 / steps, 'fs').value_in_au, split=True, imaginary=False): t = Quantity(time).convert_to(unit='fs').value p = solver.expection(op=op) logging.warning('Time: {:.2f} fs; P2: {}'.format(t, p)) tp_list.append((t, p)) return np.array(tp_list)
def sbm_zt(including_bath=False, split=False, snd=False): sbm_para_dict = { 'including_bath': including_bath, 'e1': 0., 'e2': Quantity(6500, 'cm-1').value_in_au, 'v': Quantity(500, 'cm-1').value_in_au, "omega_list": [ Quantity(2100, 'cm-1').value_in_au, Quantity(650, 'cm-1').value_in_au, Quantity(400, 'cm-1').value_in_au, Quantity(150, 'cm-1').value_in_au ], 'lambda_list': ([Quantity(750, 'cm-1').value_in_au] * 4), 'dim_list': [10, 14, 20, 30], 'stop': Quantity(3 * 2250, 'cm-1').value_in_au, 'n': 32, 'dim': 30, 'lambda_g': Quantity(2250, 'cm-1').value_in_au, 'omega_g': Quantity(500, 'cm-1').value_in_au, 'lambda_d': Quantity(1250, 'cm-1').value_in_au, 'omega_d': Quantity(50, 'cm-1').value_in_au, 'mu': Quantity(250, 'cm-1').value_in_au, 'tau': Quantity(30, 'fs').value_in_au, 't_d': Quantity(60, 'fs').value_in_au, 'omega': Quantity(13000, 'cm-1').value_in_au, } sbm = SpinBosonModel(**sbm_para_dict) # Define the topological structure of the ML-MCTDH tree graph, root = sbm.autograph(n_branch=2) root = Tensor.generate(graph, root) # Define the detailed parameters for the MC-MCTDH tree solver = MultiLayer(root, sbm.h_list, f_list=sbm.f_list, use_str_name=True) bond_dict = {} # Leaves for s, i, t, j in root.linkage_visitor(): if isinstance(t, Leaf): bond_dict[(s, i, t, j)] = sbm.dimensions[t.name] # ELEC part elec_r = root[0][0] for s, i, t, j in elec_r.linkage_visitor(leaf=False): raise NotImplementedError() # INNER part inner_r = root[1][0] if including_bath else root if including_bath: bond_dict[(root, 1, inner_r, 0)] = 60 for s, i, t, j in inner_r.linkage_visitor(leaf=False): bond_dict[(s, i, t, j)] = 50 # OUTER part if including_bath: outer_r = root[2][0] bond_dict[(root, 2, outer_r, 0)] = 20 for s, i, t, j in root[2][0].linkage_visitor(leaf=False): bond_dict[(s, i, t, j)] = 10 solver.autocomplete(bond_dict, max_entangled=False) # Define the computation details solver.settings( max_ode_steps=100, cmf_steps=(1 if split else 10), ode_method='RK45', ps_method='s', snd_order=snd, ) root.is_normalized = True # Define the obersevable of interest projector = np.array([[0., 0.], [0., 1.]]) op = [[[root[0][0], projector]]] t_p = [] for time, _ in solver.propagator( steps=20, ode_inter=Quantity(0.2, 'fs').value_in_au, split=split, move_energy=True, ): t, p = (Quantity(time).convert_to(unit='fs').value, solver.expection(op=op)) t_p.append((t, p)) logging.warning('Time: {:.2f} fs, P2: {}'.format(t, p)) if np.abs(p) > 0.5: break # Save the results msg = 'split' if split else 'origin' msg2 = 'snd' if snd else 'fst' np.savetxt('sbm-zt-{}-{}.dat'.format(msg, msg2), t_p)
Acting on 0-th index. """ derivatives = self._diff_h() + self._diff_n() for k in range(self.k_max): derivatives.extend(self._diff_k(k)) return derivatives if __name__ == '__main__': from minitn.heom.noise import Drude from minitn.lib.units import Quantity # System e = Quantity(6500, 'cm-1').value_in_au v = Quantity(500, 'cm-1').value_in_au # Bath lambda_0 = Quantity(2000, 'cm-1').value_in_au # reorganization energy omega_0 = Quantity(2000, 'cm-1').value_in_au # vibrational frequency beta = Quantity(300, 'K').value_in_au # temperature # Superparameters max_terms = 5 # (terms used in the expansion of the correlation function) max_tier = 10 # (number of possble values for each n_k in the extended rho) h = np.array([[0, v], [v, e]]) op = np.array([[0, 0], [0, 1]]) corr = Drude(lambda_0, omega_0, max_terms, beta) heom = Hierachy([max_tier] * max_terms, h, op, corr)
def sbm_zt(including_bath=False, split=False, snd=False): omega = 13000 sbm = SpinBosonModel( including_bath=including_bath, e1=0., e2=Quantity(6500, 'cm-1').value_in_au, v=Quantity(500, 'cm-1').value_in_au, omega_list=[ Quantity(2100, 'cm-1').value_in_au, Quantity(650, 'cm-1').value_in_au, Quantity(400, 'cm-1').value_in_au, Quantity(150, 'cm-1').value_in_au ], lambda_list=([Quantity(750, 'cm-1').value_in_au] * 4), dim_list=[10, 14, 20, 30], stop=Quantity(3 * 2250, 'cm-1').value_in_au, n=32, dim=30, lambda_g=Quantity(2250, 'cm-1').value_in_au, omega_g=Quantity(500, 'cm-1').value_in_au, lambda_d=Quantity(1250, 'cm-1').value_in_au, omega_d=Quantity(50, 'cm-1').value_in_au, mu=Quantity(250, 'cm-1').value_in_au, tau=Quantity(30, 'fs').value_in_au, t_d=Quantity(60, 'fs').value_in_au, omega=Quantity(omega, 'cm-1').value_in_au, ) # Define the topological structure of the ML-MCTDH tree graph, root = sbm.autograph(n_branch=2) root = Tensor.generate(graph, root) # Define the detailed parameters for the MC-MCTDH tree solver = MultiLayer(root, sbm.h_list, f_list=sbm.f_list, use_str_name=True) bond_dict = {} # Leaves for s, i, t, j in root.linkage_visitor(): if isinstance(t, Leaf): bond_dict[(s, i, t, j)] = sbm.dimensions[t.name] # ELEC part elec_r = root[0][0] for s, i, t, j in elec_r.linkage_visitor(leaf=False): raise NotImplementedError() # INNER part inner_r = root[1][0] if including_bath else root if including_bath: bond_dict[(root, 1, inner_r, 0)] = 60 for s, i, t, j in inner_r.linkage_visitor(leaf=False): bond_dict[(s, i, t, j)] = 50 # OUTER part if including_bath: outer_r = root[2][0] bond_dict[(root, 2, outer_r, 0)] = 20 for s, i, t, j in root[2][0].linkage_visitor(leaf=False): bond_dict[(s, i, t, j)] = 10 solver.autocomplete(bond_dict, max_entangled=False) # Define the computation details solver.settings( max_ode_steps=100, cmf_steps=(1 if split else 10), ode_method='RK45', ps_method='s', snd_order=snd, ) print("Size of a wfn: {} complexes".format(len(root.vectorize()))) root.is_normalized = True # Define the obersevable of interest projector = np.array([[0., 0.], [0., 1.]]) op = [[[root[0][0], projector]]] t_p = [] for time, _ in solver.propagator( steps=20, ode_inter=Quantity(0.2, 'fs').value_in_au, split=split, move_energy=True, ): t, p = (Quantity(time).convert_to(unit='fs').value, solver.expection(op=op)) t_p.append((t, p)) logging.warning('Time: {:.2f} fs, P2: {}'.format(t, p)) if np.abs(p) > 0.5: break return np.array(t_p)
from __future__ import absolute_import, division, print_function from builtins import filter, map, range, zip from minitn.heom.corr import Drude from minitn.heom.network import tensor_train_template from minitn.heom.propagate import MultiLayer from minitn.lib.backend import DTYPE, np from minitn.lib.logging import Logger from minitn.lib.tools import huffman_tree from minitn.lib.units import Quantity from minitn.models.sbm import SBM from minitn.tensor import Leaf, Tensor # System: pure dephasing e = Quantity(5000, 'cm-1').value_in_au v = Quantity(500, 'cm-1').value_in_au max_tier = 40 rank_heom = max_tier rank_wfn = max_tier beta = Quantity(1 / 300, 'K-1').value_in_au prefix = 'drude_100_300K_t{}_'.format(max_tier) ph_parameters = [ #(Quantity(400, 'cm-1').value_in_au, Quantity(500, 'cm-1').value_in_au), #(Quantity(800, 'cm-1').value_in_au, Quantity(500, 'cm-1').value_in_au), #(Quantity(1200, 'cm-1').value_in_au, Quantity(500, 'cm-1').value_in_au), #(Quantity(1600, 'cm-1').value_in_au, Quantity(500, 'cm-1').value_in_au), ] dof = len(ph_parameters)
def ml(dof, e, v, eta, cutoff, scale=5, loc=None, steps=2000, ode_inter=0.1): f_ = 'dof{}-eta{}.log'.format(dof, eta) logger = Logger(filename=f_).logger # define parameters e = Quantity(e, 'cm-1').value_in_au v = Quantity(v, 'cm-1').value_in_au eta = Quantity(eta, 'cm-1').value_in_au omega0 = Quantity(cutoff, 'cm-1').value_in_au sys_hamiltonian = np.array([[-e / 2.0, v], [v, e / 2.0]], dtype=DTYPE) projector = np.array([[0.0, 0.0], [0.0, 1.0]], dtype=DTYPE) # S in H_SB = S x B primitive_dim = 100 spf_dim = 20 # Spectrum function def spec_func(omega): if 0 < omega < omega0: return eta else: return 0.0 # Define all Leaf tensors and hamiltonian we need h_list = [] sys_leaf = Leaf(name='sys0') h_list.append([(sys_leaf, -1.0j * sys_hamiltonian)]) ph_parameters = linear_discretization(spec_func, omega0, dof) if loc is not None: adj_pair = (ph_parameters[loc][0], ph_parameters[loc][1] * scale) ph_parameters[loc] = adj_pair leaves = [] for n, (omega, g) in enumerate(ph_parameters, 1): ph = Phonon(primitive_dim, omega) ph_leaf = Leaf(name='ph{}'.format(n)) leaves.append(ph_leaf) # hamiltonian ph part h_list.append([(ph_leaf, -1.0j * ph.hamiltonian)]) # e-ph part op = ph.annihilation_operator + ph.creation_operator h_list.append([(ph_leaf, g * op), (sys_leaf, -1.0j * projector)]) def ph_spf(n=0): n += 1 return Tensor(name='spf{}'.format(n), axis=0) graph, root = huffman_tree(leaves, obj_new=ph_spf, n_branch=2) try: graph[root].insert(0, sys_leaf) except KeyError: ph_leaf = root root = Tensor() graph[root] = [sys_leaf, ph_leaf] finally: root.name = 'wfn' root.axis = None print(graph) stack = [root] while stack: parent = stack.pop() for child in graph[parent]: parent.link_to(parent.order, child, 0) if child in graph: stack.append(child) # Define the detailed parameters for the ML-MCTDH tree solver = MultiLayer(root, h_list) bond_dict = {} # Leaves for s, i, t, j in root.linkage_visitor(): if t.name.startswith('sys'): bond_dict[(s, i, t, j)] = 2 else: if isinstance(t, Leaf): bond_dict[(s, i, t, j)] = primitive_dim else: bond_dict[(s, i, t, j)] = spf_dim solver.autocomplete(bond_dict) # set initial root array a, b = 1.0, 1.0 init_proj = np.array([[a, 0.0], [b, 0.0]]) / np.sqrt(a**2 + b**2) root_array = Tensor.partial_product(root.array, 0, init_proj, 1) root.set_array(root_array) # Define the computation details solver.ode_method = 'RK45' solver.snd_order = True solver.cmf_steps = 1 root.is_normalized = True # Define the obersevable of interest logger.info('''# time/fs rho00 rho01 rho10 rho11''') for time, _ in solver.propagator( steps=steps, ode_inter=Quantity(ode_inter, 'fs').value_in_au, split=True, ): t = Quantity(time).convert_to(unit='fs').value for tensor in root.visitor(axis=None): tensor.reset() rho = root.partial_env(0, proper=False) for tensor in root.visitor(axis=None): tensor.reset() flat_data = [t] + list(np.reshape(rho, -1)) logger.info('{} {} {} {} {}'.format(*flat_data))