def tensor_tree_template(init_rho, pb_index, rank=1, nbranch=2): """Get rho_n from rho in a Tensor Tree representation. Parameters ---------- rho : np.ndarray """ n_state = get_n_state(init_rho) n_vec = np.zeros((rank, ), dtype=DTYPE) n_vec[0] = 1.0 root_array = np.tensordot(init_rho, n_vec, axes=0) max_terms = len(pb_index) for i in pb_index: assert rank <= i # generate leaves leaves = list(range(max_terms)) class new_spf(object): counter = 0 prefix = 'SPF' def __new__(cls): name = cls.prefix + str(cls.counter) cls.counter += 1 return name importance = list(reversed(range(len(pb_index)))) graph, spf_root = huffman_tree( leaves, importances=importance, obj_new=new_spf, n_branch=nbranch, ) root = 'root' graph[root] = [str(max_terms), str(max_terms + 1), spf_root] print(graph, root) root = Tensor.generate(graph, root) root.set_array(root_array) bond_dict = {} # Leaves l_range = list(pb_index) + [n_state] * 2 for s, i, t, j in root.linkage_visitor(): if isinstance(t, Leaf): bond_dict[(s, i, t, j)] = l_range[int(t.name)] else: bond_dict[(s, i, t, j)] = rank autocomplete(root, bond_dict) return root
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)
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): 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)