Esempio n. 1
0
 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
Esempio n. 2
0
 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
Esempio n. 3
0
    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
Esempio n. 4
0
 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)
Esempio n. 5
0
    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
Esempio n. 6
0
 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
Esempio n. 7
0
 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
Esempio n. 8
0
 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
Esempio n. 9
0
 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
Esempio n. 10
0
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))
Esempio n. 11
0
 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
Esempio n. 12
0
 def global_norm(self):
     return np.sqrt(self.global_square())
Esempio n. 13
0
    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
Esempio n. 14
0
 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
Esempio n. 15
0
 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
Esempio n. 16
0
    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))
Esempio n. 17
0
 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)
Esempio n. 18
0
    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()
Esempio n. 19
0
 def _sqrt_numberer(self, k, start=0):
     return np.diag(
         np.sqrt(np.arange(start, start + self.n_dims[k], dtype=DTYPE)))
Esempio n. 20
0
 def local_norm(self):
     self.aux = np.conj(self.array)
     ans = self.local_inner_product()
     return np.sqrt(ans)