def _phi(_x): phi = np.where( np.logical_and(x0 < _x, _x < x0 + L), np.sqrt(2. / L) * np.sin(j * np.pi * (_x - x0) / L), 0 ) return phi
def _calculate_dvr(self): # calculate grid points step_length = self.length / (self.n + 1) self.grid_points = np.array([self.a + step_length * i for i in range(1, self.n + 1)]) # calculate U matrix j = np.arange(1, self.n + 1)[:, None] a = np.arange(1, self.n + 1)[None, :] self._u_mat = (np.sqrt(2 / (self.n + 1)) * np.sin(j * a * np.pi / (self.n + 1))) return self.grid_points, self._u_mat
def momentum_operator(self): coeff = 1.0j * np.sqrt(self.hbar * self.mass * self.omega / 2.) if self.dense: ans = coeff * (self.creation_operator - self.annihilation_operator) else: def matvec(x): return coeff * (self.raising(x) - self.lowering(x)) ans = self.operator(matvec=matvec) return ans
def inner_hamiltonian(self, prefix='I'): omega_list, lambda_list, dim_list = [ getattr(self, name) for name in self.INNER ] coupling_list = list( np.sqrt(np.array(lambda_list) / 2) * np.array(omega_list)) self.inner_prefix = prefix return self.vibration_hamiltonian(omega_list, coupling_list, dim_list, prefix=prefix)
def coordinate_operator(self): coeff = np.sqrt(self.hbar / self.mass / self.omega / 2.) if self.dense: ans = coeff * (self.creation_operator + self.annihilation_operator) else: def matvec(x): return coeff * (self.raising(x) + self.lowering(x)) ans = self.operator(matvec=matvec) return ans
def annihilation_operator(self): if self.dense: ans = np.diag(np.sqrt(np.arange(1, self.dim)), 1) else: ans = self.operator(matvec=self.lowering, rmatvec=self.raising) return ans
def lowering(self, vec): self.check_vec(vec) ans = np.zeros_like(vec) tmp = np.array([np.sqrt(i) for i in range(self.dim)]) * vec ans[:-1] = tmp[1:] return ans
def raising(self, vec): self.check_vec(vec) ans = np.zeros_like(vec) ans[1:] = vec[:-1] ans *= np.array([np.sqrt(i) for i in range(self.dim)]) return ans
def direct_quad(a, b): density = quad(spec_func, a, b)[0] omega = quad(lambda x: x * spec_func(x), a, b)[0] / density coupling = np.sqrt(density) return omega, coupling
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))
def _bimodal_spectral_density(omega): gaussian = ((np.sqrt(np.pi) * lambda_g * omega) / (4. * omega_g) * np.exp(-(omega / (2. * omega_g))**2)) debye = ((lambda_d * omega * omega_d) / (2 * (omega_d**2 + omega**2))) return gaussian + debye
def global_norm(self): return np.sqrt(self.global_square())
def autocomplete(self, n_bond_dict, max_entangled=False): """Autocomplete the tensors linked to `self.root` with suitable initial value. Parameters ---------- n_bond_dict : {Leaf: int} A dictionary to specify the dimensions of each primary basis. max_entangled : bool Whether to use the max entangled state as initial value (for finite temperature and imaginary-time propagation). Default is `False`. """ for t in self.root.visitor(leaf=False): if t.array is None: axis = t.axis if max_entangled and not any(t.children(leaf=False)): if len(list(t.children(leaf=True))) != 2 or axis is None: raise RuntimeError('Not correct tensor graph for FT.') for i, leaf, j in t.children(): if not leaf.name.endswith("'"): n_leaf = n_bond_dict[(t, i, leaf, j)] break p, p_i = t[axis] n_parent = n_bond_dict[(p, p_i, t, axis)] vec_i = np.diag(np.ones((n_leaf, )) / np.sqrt(n_leaf)) vec_i = np.reshape(vec_i, -1) init_vecs = [vec_i] print(np.shape(init_vecs), np.shape(self._local_matvec(leaf))) da = DavidsonAlgorithm(self._local_matvec(leaf), init_vecs=init_vecs, n_vals=n_parent) array = da.kernel(search_mode=True) if len(array) >= n_parent: array = array[:n_parent] else: for j in range(n_parent - len(array)): v = np.zeros((n_leaf**2, )) v[j] = 1.0 array.append(v) assert len(array) == n_parent assert np.allclose(array[0], vec_i) array = np.reshape(array, (n_parent, n_leaf, n_leaf)) else: n_children = [] for i, child, j in t.children(): n_children.append(n_bond_dict[(t, i, child, j)]) if axis is not None: p, p_i = t[axis] n_parent = n_bond_dict[(p, p_i, t, axis)] shape = [n_parent] + n_children else: n_parent = 1 shape = n_children array = np.zeros((n_parent, np.prod(n_children))) for n, v_i in zip(self.triangular(n_children), array): v_i[n] = 1. array = np.reshape(array, shape) if axis is not None: array = np.moveaxis(array, 0, axis) t.set_array(array) t.normalize(forced=True) assert (t.axis is None or np.linalg.matrix_rank(t.local_norm()) == t.shape[t.axis]) if __debug__: for t in self.root.visitor(): t.check_completness(strict=True) return
def annihilator(self, k): """Acting on 0-th index""" dim = self.n_dims[k] lower = np.eye(dim, k=-1) sqrt_n = np.diag(np.sqrt(np.arange(dim))) return sqrt_n @ lower
def creator(self, k): """Acting on 0-th index""" dim = self.n_dims[k] raiser = np.eye(dim, k=1) sqrt_n = np.diag(np.sqrt(np.arange(dim))) return raiser @ sqrt_n
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) phi = [1 / np.sqrt(2), 1 / np.sqrt(2)] phi /= np.linalg.norm(phi) rho_0 = np.tensordot(phi, phi, axes=0) init_rho = heom.gen_extended_rho(rho_0) print(init_rho.shape) for n, term in enumerate(heom.diff()): print('- Term {}:'.format(n)) for label, array in term: print('Label: {}, shape: {}'.format(label, array.shape))
def _lower(self, k): """Acting on 0-th index""" dim = self.n_dims[k] sqrt_n = np.diag(np.sqrt(np.arange(dim, dtype=DTYPE))) return sqrt_n @ np.eye(dim, k=-1, dtype=DTYPE)
lambda_=Quantity(400, 'cm-1').value_in_au, beta=beta, ) 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), ph_parameters=ph_parameters, ph_dims=(dof * [max_tier]), bath_corr=drude, bath_dims=[max_tier], ) # init state A, B = 1.0, 1.0 wfn_0 = np.array([A, B]) / np.sqrt(A**2 + B**2) rho_0 = np.tensordot(wfn_0, wfn_0, axes=0) # Propagation dt_unit = Quantity(0.001, 'fs').value_in_au callback_interval = 100 count = 10_000 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()
def _sqrt_numberer(self, k, start=0): return np.diag( np.sqrt(np.arange(start, start + self.n_dims[k], dtype=DTYPE)))
def local_norm(self): self.aux = np.conj(self.array) ans = self.local_inner_product() return np.sqrt(ans)