Пример #1
0
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
Пример #2
0
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)
Пример #3
0
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)
Пример #4
0
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)