def test_hops_adaptive_dynamics_full(): """ This is a test of the adaptive dynamics algorithm when threshold is small enough that all states and hierarchy are included. """ hops_ah = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 2}, eom_param=eom_param, ) hops_ah.make_adaptive(1e-15, 0) hops_ah.initialize(psi_0) hops_ah.propagate(t_max, t_step) np.testing.assert_allclose(hops.psi_traj[33], hops_ah.psi_traj[33]) hops_as = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 2}, eom_param=eom_param, ) hops_as.make_adaptive(0, 1e-100) hops_as.initialize(psi_0) hops_as.propagate(t_max, t_step) np.testing.assert_allclose(hops.psi_traj[33], hops_as.psi_traj[33]) hops_a = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 2}, eom_param=eom_param, ) hops_a.make_adaptive(1e-15, 1e-100) hops_a.initialize(psi_0) hops_a.propagate(t_max, t_step) np.testing.assert_allclose(hops.psi_traj[33], hops_a.psi_traj[33])
def test_hops_adaptive_dynamics_partial(): """ This is a test of the adaptive dynamics algorithm when threshold is large enough that some states and auxiliaries are missing. """ # Test adaptive hierarchy # ======================= hops_ah = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 2}, eom_param=eom_param, ) hops_ah.make_adaptive(1e-3, 0) hops_ah.initialize(psi_0) hops_ah.propagate(t_max, t_step) # Construct permutation for full-->reduced basis # ---------------------------------------------- P2_permute = construct_permute_matrix(hops_ah.auxiliary_list, hops_ah.state_list, hops) # Permute super operators from hops into reduced basis # ---------------------------------------------------- K0 = _permute_aux_by_matrix(hops.basis.eom.K2_k, P2_permute) Kp1 = _permute_aux_by_matrix(hops.basis.eom.K2_kp1, P2_permute) Km1 = _permute_aux_by_matrix(hops.basis.eom.K2_km1, P2_permute) Zp1 = [ _permute_aux_by_matrix(hops.basis.eom.Z2_kp1[index_l2], P2_permute) for index_l2 in hops_ah.basis.system.list_absindex_L2 ] Z0 = [ _permute_aux_by_matrix(hops.basis.eom.Z2_k[index_l2], P2_permute) for index_l2 in hops_ah.basis.system.list_absindex_L2 ] # Compare reduced hops to adhops super operators # ---------------------------------------------- assert (Kp1.todense() == hops_ah.basis.eom.K2_kp1.todense()).all() assert (Km1.todense() == hops_ah.basis.eom.K2_km1.todense()).all() assert (K0.todense() == hops_ah.basis.eom.K2_k.todense()).all() assert np.all([ np.all(Z2_k_hops.todense() == Z2_k_adhops.todense()) for (Z2_k_hops, Z2_k_adhops) in zip(Z0, hops_ah.basis.eom.Z2_k) ]) assert np.all([ np.all(Z2_kp1_hops.todense() == Z2_kp1_adhops.todense()) for (Z2_kp1_hops, Z2_kp1_adhops) in zip(Zp1, hops_ah.basis.eom.Z2_kp1) ]) # Test adaptive system # ==================== hops_ah = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 2}, eom_param=eom_param, ) hops_ah.make_adaptive(0, 1e-3) hops_ah.initialize(psi_0) hops_ah.propagate(t_max, t_step) # Construct permutation for full-->reduced basis # ---------------------------------------------- P2_permute = construct_permute_matrix(hops_ah.auxiliary_list, hops_ah.state_list, hops) # Permute super operators from hops into reduced basis # ---------------------------------------------------- K0 = _permute_aux_by_matrix(hops.basis.eom.K2_k, P2_permute) Kp1 = _permute_aux_by_matrix(hops.basis.eom.K2_kp1, P2_permute) Km1 = _permute_aux_by_matrix(hops.basis.eom.K2_km1, P2_permute) Zp1 = [ _permute_aux_by_matrix(hops.basis.eom.Z2_kp1[index_l2], P2_permute) for index_l2 in hops_ah.basis.system.list_absindex_L2 ] Z0 = [ _permute_aux_by_matrix(hops.basis.eom.Z2_k[index_l2], P2_permute) for index_l2 in hops_ah.basis.system.list_absindex_L2 ] # Compare reduced hops to adhops super operators # ---------------------------------------------- assert (Kp1.todense() == hops_ah.basis.eom.K2_kp1.todense()).all() assert (Km1.todense() == hops_ah.basis.eom.K2_km1.todense()).all() assert (K0.todense() == hops_ah.basis.eom.K2_k.todense()).all() assert np.all([ np.all(Z2_k_hops.todense() == Z2_k_adhops.todense()) for (Z2_k_hops, Z2_k_adhops) in zip(Z0, hops_ah.basis.eom.Z2_k) ]) assert np.all([ np.all(Z2_kp1_hops.todense() == Z2_kp1_adhops.todense()) for (Z2_kp1_hops, Z2_kp1_adhops) in zip(Zp1, hops_ah.basis.eom.Z2_kp1) ]) # Test adaptive system and adaptive hierarchy # =========================================== hops_ah = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 2}, eom_param=eom_param, ) hops_ah.make_adaptive(1e-3, 1e-3) hops_ah.initialize(psi_0) hops_ah.propagate(t_max, t_step) # Construct permutation for full-->reduced basis # ---------------------------------------------- P2_permute = construct_permute_matrix(hops_ah.auxiliary_list, hops_ah.state_list, hops) # Permute super operators from hops into reduced basis # ---------------------------------------------------- K0 = _permute_aux_by_matrix(hops.basis.eom.K2_k, P2_permute) Kp1 = _permute_aux_by_matrix(hops.basis.eom.K2_kp1, P2_permute) Km1 = _permute_aux_by_matrix(hops.basis.eom.K2_km1, P2_permute) Zp1 = [ _permute_aux_by_matrix(hops.basis.eom.Z2_kp1[index_l2], P2_permute) for index_l2 in hops_ah.basis.system.list_absindex_L2 ] Z0 = [ _permute_aux_by_matrix(hops.basis.eom.Z2_k[index_l2], P2_permute) for index_l2 in hops_ah.basis.system.list_absindex_L2 ] # Compare reduced hops to adhops super operators # ---------------------------------------------- assert (Kp1.todense() == hops_ah.basis.eom.K2_kp1.todense()).all() assert (Km1.todense() == hops_ah.basis.eom.K2_km1.todense()).all() assert (K0.todense() == hops_ah.basis.eom.K2_k.todense()).all() assert np.all([ np.all(Z2_k_hops.todense() == Z2_k_adhops.todense()) for (Z2_k_hops, Z2_k_adhops) in zip(Z0, hops_ah.basis.eom.Z2_k) ]) assert np.all([ np.all(Z2_kp1_hops.todense() == Z2_kp1_adhops.todense()) for (Z2_kp1_hops, Z2_kp1_adhops) in zip(Zp1, hops_ah.basis.eom.Z2_kp1) ])
def test_check_hierarchy_list(): """ Test to make sure check_state_list is giving out correct stable and bound hierarchy members """ noise_param = { "SEED": 0, "MODEL": "FFT_FILTER", "TLEN": 250.0, # Units: fs "TAU": 1.0, # Units: fs } nsite = 2 e_lambda = 20.0 gamma = 50.0 temp = 140.0 (g_0, w_0) = bcf_convert_sdl_to_exp(e_lambda, gamma, 0.0, temp) loperator = np.zeros([2, 2, 2], dtype=np.float64) gw_sysbath = [] lop_list = [] for i in range(nsite): loperator[i, i, i] = 1.0 gw_sysbath.append([g_0, w_0]) lop_list.append(sp.sparse.coo_matrix(loperator[i])) gw_sysbath.append([-1j * np.imag(g_0), 500.0]) lop_list.append(loperator[i]) hs = np.zeros([nsite, nsite], dtype=np.float64) hs[0, 1] = 40 hs[1, 0] = 40 sys_param = { "HAMILTONIAN": np.array(hs, dtype=np.complex128), "GW_SYSBATH": gw_sysbath, "L_HIER": lop_list, "L_NOISE1": lop_list, "ALPHA_NOISE1": bcf_exp, "PARAM_NOISE1": gw_sysbath, } eom_param = {"EQUATION_OF_MOTION": "NORMALIZED NONLINEAR"} integrator_param = { "INTEGRATOR": "RUNGE_KUTTA", "INCHWORM": False, "INCHWORM_MIN": 5, } psi_0 = np.array([0.0] * nsite, dtype=np.complex) psi_0[1] = 1.0 psi_0 = psi_0 / np.linalg.norm(psi_0) hops_ad = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 4}, eom_param=eom_param, integration_param=integrator_param, ) hops_ad.make_adaptive(1e-3, 1e-3) hops_ad.initialize(psi_0) # inital hierarchy z_step = [0, 0] list_aux_stable, list_aux_boundary = hops_ad.basis._check_hierarchy_list( hops_ad.phi, 2.0, z_step ) known_stable = [ AuxiliaryVector([], 4), AuxiliaryVector([(2, 1)], 4), AuxiliaryVector([(3, 1)], 4), ] assert np.array_equal(list_aux_stable, known_stable) known_boundary = [] assert tuple(known_boundary) == tuple(list_aux_boundary) # hierarchy after propagate hops_ad.propagate(12.0, 2.0) list_aux_stable, list_aux_boundary = hops_ad.basis._check_hierarchy_list( hops_ad.phi, 2.0, z_step ) known_stable = [ AuxiliaryVector([], 4), AuxiliaryVector([(0, 1)], 4), AuxiliaryVector([(1, 1)], 4), AuxiliaryVector([(2, 1)], 4), AuxiliaryVector([(3, 1)], 4), AuxiliaryVector([(0, 1), (1, 1)], 4), AuxiliaryVector([(1, 2)], 4), AuxiliaryVector([(1, 1), (2, 1)], 4), AuxiliaryVector([(1, 1), (3, 1)], 4), AuxiliaryVector([(2, 2)], 4), AuxiliaryVector([(2, 1), (3, 1)], 4), AuxiliaryVector([(3, 2)], 4), AuxiliaryVector([(1, 3)], 4), AuxiliaryVector([(1, 2), (3, 1)], 4), AuxiliaryVector([(1, 1), (3, 2)], 4), AuxiliaryVector([(2, 2), (3, 1)], 4), AuxiliaryVector([(2, 1), (3, 2)], 4), AuxiliaryVector([(3, 3)], 4), AuxiliaryVector([(1, 4)], 4), AuxiliaryVector([(1, 3), (3, 1)], 4), AuxiliaryVector([(2, 2), (3, 2)], 4), AuxiliaryVector([(2, 1), (3, 3)], 4), AuxiliaryVector([(3, 4)], 4), ] assert list_aux_stable == known_stable known_boundary = [ AuxiliaryVector([(1, 1), (3, 3)], 4), AuxiliaryVector([(1, 2), (3, 2)], 4), ] assert list_aux_boundary == known_boundary
def test_determine_boundary_hier(): """ Test to make sure correct boundary hierarchy members are accounted for """ noise_param = { "SEED": 0, "MODEL": "FFT_FILTER", "TLEN": 250.0, # Units: fs "TAU": 1.0, # Units: fs } nsite = 2 e_lambda = 20.0 gamma = 50.0 temp = 140.0 (g_0, w_0) = bcf_convert_sdl_to_exp(e_lambda, gamma, 0.0, temp) loperator = np.zeros([2, 2, 2], dtype=np.float64) gw_sysbath = [] lop_list = [] for i in range(nsite): loperator[i, i, i] = 1.0 gw_sysbath.append([g_0, w_0]) lop_list.append(sp.sparse.coo_matrix(loperator[i])) gw_sysbath.append([-1j * np.imag(g_0), 500.0]) lop_list.append(loperator[i]) hs = np.zeros([nsite, nsite], dtype=np.float64) hs[0, 1] = 40 hs[1, 0] = 40 sys_param = { "HAMILTONIAN": np.array(hs, dtype=np.complex128), "GW_SYSBATH": gw_sysbath, "L_HIER": lop_list, "L_NOISE1": lop_list, "ALPHA_NOISE1": bcf_exp, "PARAM_NOISE1": gw_sysbath, } eom_param = {"EQUATION_OF_MOTION": "NORMALIZED NONLINEAR"} integrator_param = { "INTEGRATOR": "RUNGE_KUTTA", "INCHWORM": False, "INCHWORM_MIN": 5, } psi_0 = np.array([0.0] * nsite, dtype=np.complex) psi_0[1] = 1.0 psi_0 = psi_0 / np.linalg.norm(psi_0) hops_ad = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 4}, eom_param=eom_param, integration_param=integrator_param, ) hops_ad.make_adaptive(1e-3, 1e-3) hops_ad.initialize(psi_0) # Creating flux up and flux down matrices for initial hierarchy # flux down flux_down = np.zeros((4, 3)) # flux up flux_up = np.zeros((4, 3)) flux_up[2, 0] = 0.1 flux_up[3, 0] = 0.001 list_e2_kflux = np.array((flux_up, flux_down)) list_index_stable = [0, 1, 2] list_aux_up, list_aux_down = hops_ad.basis._determine_boundary_hier( list_e2_kflux, list_index_stable, 0.001 ) known_aux_up = [AuxiliaryVector([(2, 1)], 4)] assert list_aux_up == known_aux_up assert list_aux_down == [] # Creating flux up and flux down matrices for hierarchy after propagation hops_ad.propagate(4.0, 2.0) # flux up flux_up = np.zeros((4, 12)) flux_up[0, 0] = 0.01 flux_up[0, 6] = 0.01 flux_up[1, 7] = 0.00004 flux_up[2, 3] = 0.1 flux_up[2, 10] = 0.00007 flux_up[3, 9] = 0.0011 # flux down flux_down = np.zeros((4, 12)) flux_down[1, 1] = 0.1 flux_down[2, 2] = 0.1 flux_down[2, 10] = 0.1 flux_down[2, 6] = 0.00007 list_e2_kflux = np.array((flux_up, flux_down)) list_index_stable = [6, 4, 10, 11, 5, 7, 1, 9, 0, 3, 8, 2] list_index_stable.sort() list_aux_up, list_aux_down = hops_ad.basis._determine_boundary_hier( list_e2_kflux, list_index_stable, 0.001 ) known_aux_up = [ AuxiliaryVector([(0, 1)], 4), AuxiliaryVector([(0, 1), (2, 1), (3, 1)], 4), AuxiliaryVector([(2, 1), (3, 1)], 4), AuxiliaryVector([(3, 4)], 4), ] assert list_aux_up == known_aux_up assert list_aux_down == [ AuxiliaryVector([], 4), AuxiliaryVector([], 4), AuxiliaryVector([(3, 3)], 4), ]
def test_update_basis(): """ Test to make sure the basis is getting properly updated and returning the updated phi and dsystem_dt """ noise_param = { "SEED": 0, "MODEL": "FFT_FILTER", "TLEN": 250.0, # Units: fs "TAU": 1.0, # Units: fs } nsite = 10 e_lambda = 20.0 gamma = 50.0 temp = 140.0 (g_0, w_0) = bcf_convert_sdl_to_exp(e_lambda, gamma, 0.0, temp) loperator = np.zeros([10, 10, 10], dtype=np.float64) gw_sysbath = [] lop_list = [] for i in range(nsite): loperator[i, i, i] = 1.0 gw_sysbath.append([g_0, w_0]) lop_list.append(sp.sparse.coo_matrix(loperator[i])) gw_sysbath.append([-1j * np.imag(g_0), 500.0]) lop_list.append(loperator[i]) hs = np.zeros([nsite, nsite]) hs[0, 1] = 40 hs[1, 0] = 40 hs[1, 2] = 10 hs[2, 1] = 10 hs[2, 3] = 40 hs[3, 2] = 40 hs[3, 4] = 10 hs[4, 3] = 10 hs[4, 5] = 40 hs[5, 4] = 40 hs[5, 6] = 10 hs[6, 5] = 10 hs[6, 7] = 40 hs[7, 6] = 40 hs[7, 8] = 10 hs[8, 7] = 10 hs[8, 9] = 40 hs[9, 8] = 40 sys_param = { "HAMILTONIAN": np.array(hs, dtype=np.complex128), "GW_SYSBATH": gw_sysbath, "L_HIER": lop_list, "L_NOISE1": lop_list, "ALPHA_NOISE1": bcf_exp, "PARAM_NOISE1": gw_sysbath, } eom_param = {"EQUATION_OF_MOTION": "NORMALIZED NONLINEAR"} integrator_param = { "INTEGRATOR": "RUNGE_KUTTA", "INCHWORM": False, "INCHWORM_MIN": 5, } psi_0 = np.array([0.0] * nsite, dtype=np.complex) psi_0[5] = 1.0 psi_0 = psi_0 / np.linalg.norm(psi_0) hops_ad = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 4}, eom_param=eom_param, integration_param=integrator_param, ) hops_ad.make_adaptive(1e-3, 1e-3) hops_ad.initialize(psi_0) hops_ad.propagate(2, 2) # state update state_new = [3, 4, 5, 6, 7] state_stable = [4, 5, 6] state_bound = [3, 7] state_update = (state_new, state_stable, state_bound) # hierarchy update hier_new = [ AuxiliaryVector([], 20), AuxiliaryVector([(5, 1)], 20), AuxiliaryVector([(9, 1)], 20), AuxiliaryVector([(10, 1)], 20), AuxiliaryVector([(11, 1)], 20), AuxiliaryVector([(13, 1)], 20), AuxiliaryVector([(14, 1)], 20), AuxiliaryVector([(10, 1), (11, 1)], 20), AuxiliaryVector([(11, 2)], 20), AuxiliaryVector([(10, 1), (11, 2)], 20), AuxiliaryVector([(11, 3)], 20), AuxiliaryVector([(11, 4)], 20), ] hier_stable = [ AuxiliaryVector([], 20), AuxiliaryVector([(9, 1)], 20), AuxiliaryVector([(10, 1)], 20), AuxiliaryVector([(11, 1)], 20), AuxiliaryVector([(10, 1), (11, 1)], 20), AuxiliaryVector([(11, 2)], 20), AuxiliaryVector([(10, 1), (11, 2)], 20), AuxiliaryVector([(11, 3)], 20), AuxiliaryVector([(11, 4)], 20), ] hier_bound = [ AuxiliaryVector([(5, 1)], 20), AuxiliaryVector([(13, 1)], 20), AuxiliaryVector([(14, 1)], 20), ] hier_update = (hier_new, hier_stable, hier_bound) phi, _ = hops_ad.basis.update_basis(hops_ad.phi, state_update, hier_update) P2 = hops_ad.phi.view().reshape([3, 9], order="F") P2_new = phi.view().reshape([hops_ad.n_state, hops_ad.n_hier], order="F") assert np.shape(P2) == np.shape(np.zeros((3, 9))) assert np.shape(P2_new) == np.shape(np.zeros((5, 12))) assert P2[1, 5] == P2_new[2, 8] assert P2[1, 1] == P2_new[2, 2] assert P2[1, 7] == P2_new[2, 10] assert P2[2, 3] == P2_new[3, 4]
def test_check_state_list(): """ Test to make sure check_state_list is giving out correct stable and bound states """ noise_param = { "SEED": 0, "MODEL": "FFT_FILTER", "TLEN": 250.0, # Units: fs "TAU": 1.0, # Units: fs } nsite = 10 e_lambda = 20.0 gamma = 50.0 temp = 140.0 (g_0, w_0) = bcf_convert_sdl_to_exp(e_lambda, gamma, 0.0, temp) loperator = np.zeros([10, 10, 10], dtype=np.float64) gw_sysbath = [] lop_list = [] for i in range(nsite): loperator[i, i, i] = 1.0 gw_sysbath.append([g_0, w_0]) lop_list.append(sp.sparse.coo_matrix(loperator[i])) gw_sysbath.append([-1j * np.imag(g_0), 500.0]) lop_list.append(loperator[i]) hs = np.zeros([nsite, nsite]) hs[0, 1] = 40 hs[1, 0] = 40 hs[1, 2] = 10 hs[2, 1] = 10 hs[2, 3] = 40 hs[3, 2] = 40 hs[3, 4] = 10 hs[4, 3] = 10 hs[4, 5] = 40 hs[5, 4] = 40 hs[5, 6] = 10 hs[6, 5] = 10 hs[6, 7] = 40 hs[7, 6] = 40 hs[7, 8] = 10 hs[8, 7] = 10 hs[8, 9] = 40 hs[9, 8] = 40 sys_param = { "HAMILTONIAN": np.array(hs, dtype=np.complex128), "GW_SYSBATH": gw_sysbath, "L_HIER": lop_list, "L_NOISE1": lop_list, "ALPHA_NOISE1": bcf_exp, "PARAM_NOISE1": gw_sysbath, } eom_param = {"EQUATION_OF_MOTION": "NORMALIZED NONLINEAR"} integrator_param = { "INTEGRATOR": "RUNGE_KUTTA", "INCHWORM": False, "INCHWORM_MIN": 5, } psi_0 = np.array([0.0] * nsite, dtype=np.complex) psi_0[5] = 1.0 psi_0 = psi_0 / np.linalg.norm(psi_0) hops_ad = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 2}, eom_param=eom_param, integration_param=integrator_param, ) hops_ad.make_adaptive(1e-3, 1e-3) hops_ad.initialize(psi_0) # before propagation z_step = np.zeros(10) list_index_aux_stable = [0, 1, 2] list_stable_state, list_state_bound = hops_ad.basis._check_state_list( hops_ad.phi, 2.0, z_step, list_index_aux_stable ) known_states = [4, 5, 6] assert np.array_equal(list_stable_state, known_states) assert np.array_equal(list_state_bound, []) # propagate hops_ad.propagate(10.0, 2.0) list_stable_state, list_state_bound = hops_ad.basis._check_state_list( hops_ad.phi, 2.0, z_step, list_index_aux_stable ) known_states = [4, 5, 6] assert np.array_equal(list_stable_state, known_states) known_boundary = [3, 7] assert np.array_equal(list_state_bound, known_boundary)
def test_error_flux_down(): """ test for the error induced by neglecting flux from H_0 (or H_S) to auxiliaries with higher summed index in H_0^C. """ noise_param = { "SEED": 0, "MODEL": "FFT_FILTER", "TLEN": 250.0, # Units: fs "TAU": 1.0, # Units: fs } nsite = 2 e_lambda = 20.0 gamma = 50.0 temp = 140.0 (g_0, w_0) = bcf_convert_sdl_to_exp(e_lambda, gamma, 0.0, temp) loperator = np.zeros([2, 2, 2], dtype=np.float64) gw_sysbath = [] lop_list = [] for i in range(nsite): loperator[i, i, i] = 1.0 gw_sysbath.append([g_0, w_0]) lop_list.append(sp.sparse.coo_matrix(loperator[i])) gw_sysbath.append([-1j * np.imag(g_0), 500.0]) lop_list.append(loperator[i]) hs = np.zeros([nsite, nsite], dtype=np.float64) hs[0, 1] = 40 hs[1, 0] = 40 sys_param = { "HAMILTONIAN": np.array(hs, dtype=np.complex128), "GW_SYSBATH": gw_sysbath, "L_HIER": lop_list, "L_NOISE1": lop_list, "ALPHA_NOISE1": bcf_exp, "PARAM_NOISE1": gw_sysbath, } eom_param = {"EQUATION_OF_MOTION": "NORMALIZED NONLINEAR"} integrator_param = { "INTEGRATOR": "RUNGE_KUTTA", "INCHWORM": False, "INCHWORM_MIN": 5, } psi_0 = np.array([0.0] * nsite, dtype=np.complex) psi_0[1] = 1.0 psi_0 = psi_0 / np.linalg.norm(psi_0) hops_ad = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 4}, eom_param=eom_param, integration_param=integrator_param, ) hops_ad.make_adaptive(1e-3, 1e-3) hops_ad.initialize(psi_0) error = hops_ad.basis.error_flux_down(hops_ad.phi, "H") known_error = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] assert np.allclose(error, known_error) hops_ad.propagate(4, 2) known_error = [ [ 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, ], [ 0.00000000e00, 1.77300996e-06, 0.00000000e00, 0.00000000e00, 3.42275816e-07, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00, ], [ 0.00000000e00, 0.00000000e00, 1.11871052e-03, 0.00000000e00, 0.00000000e00, 3.12152420e-05, 3.51225702e-04, 0.00000000e00, 1.09725980e-04, 0.00000000e00, 3.31052922e-05, 0.00000000e00, ], [ 0.00000000e00, 0.00000000e00, 0.00000000e00, 2.36349134e-04, 0.00000000e00, 0.00000000e00, 8.74004868e-06, 7.42495639e-05, 2.73046762e-06, 2.30899011e-05, 8.23806071e-07, 7.44294797e-06, ], ] error = hops_ad.basis.error_flux_down(hops_ad.phi, "H") print(error) assert np.allclose(error, known_error)
def test_error_sflux_hier(): """ test for the error introduced by losing flux within k from S_0 to S_0^C for each k in H_0 """ noise_param = { "SEED": 0, "MODEL": "FFT_FILTER", "TLEN": 250.0, # Units: fs "TAU": 1.0, # Units: fs } nsite = 10 e_lambda = 20.0 gamma = 50.0 temp = 140.0 (g_0, w_0) = bcf_convert_sdl_to_exp(e_lambda, gamma, 0.0, temp) loperator = np.zeros([10, 10, 10], dtype=np.float64) gw_sysbath = [] lop_list = [] for i in range(nsite): loperator[i, i, i] = 1.0 gw_sysbath.append([g_0, w_0]) lop_list.append(sp.sparse.coo_matrix(loperator[i])) gw_sysbath.append([-1j * np.imag(g_0), 500.0]) lop_list.append(loperator[i]) hs = np.zeros([nsite, nsite]) hs[0, 1] = 40 hs[1, 0] = 40 hs[1, 2] = 10 hs[2, 1] = 10 hs[2, 3] = 40 hs[3, 2] = 40 hs[3, 4] = 10 hs[4, 3] = 10 hs[4, 5] = 40 hs[5, 4] = 40 hs[5, 6] = 10 hs[6, 5] = 10 hs[6, 7] = 40 hs[7, 6] = 40 hs[7, 8] = 10 hs[8, 7] = 10 hs[8, 9] = 40 hs[9, 8] = 40 sys_param = { "HAMILTONIAN": np.array(hs, dtype=np.complex128), "GW_SYSBATH": gw_sysbath, "L_HIER": lop_list, "L_NOISE1": lop_list, "ALPHA_NOISE1": bcf_exp, "PARAM_NOISE1": gw_sysbath, } eom_param = {"EQUATION_OF_MOTION": "NORMALIZED NONLINEAR"} integrator_param = { "INTEGRATOR": "RUNGE_KUTTA", "INCHWORM": False, "INCHWORM_MIN": 5, } psi_0 = np.array([0.0] * nsite, dtype=np.complex) psi_0[5] = 1.0 psi_0 = psi_0 / np.linalg.norm(psi_0) hops_ad = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 2}, eom_param=eom_param, integration_param=integrator_param, ) hops_ad.make_adaptive(1e-3, 1e-3) hops_ad.initialize(psi_0) E2_flux_state = hops_ad.basis.error_sflux_hier(hops_ad.phi, [4, 5, 6]) known_error = [0, 0, 0] assert np.allclose(E2_flux_state, known_error) hops_ad.propagate(10, 2) E2_flux_state = hops_ad.basis.error_sflux_hier(hops_ad.phi, [4, 5, 6]) known_error = [ 4.41017874e-08, 6.25730675e-12, 2.79827656e-09, 8.35537498e-11, 2.83286739e-09, 2.67725191e-09, 5.43756095e-10, 7.32738552e-11, 1.25275631e-13, 1.06073503e-11, 3.93302668e-10, 3.81794277e-10, ] assert np.allclose(E2_flux_state, known_error)
def test_define_basis_state(): """ Test to check whether the correct state basis is being calculated """ noise_param = { "SEED": 0, "MODEL": "FFT_FILTER", "TLEN": 250.0, # Units: fs "TAU": 1.0, # Units: fs } nsite = 10 e_lambda = 20.0 gamma = 50.0 temp = 140.0 (g_0, w_0) = bcf_convert_sdl_to_exp(e_lambda, gamma, 0.0, temp) loperator = np.zeros([10, 10, 10], dtype=np.float64) gw_sysbath = [] lop_list = [] for i in range(nsite): loperator[i, i, i] = 1.0 gw_sysbath.append([g_0, w_0]) lop_list.append(sp.sparse.coo_matrix(loperator[i])) gw_sysbath.append([-1j * np.imag(g_0), 500.0]) lop_list.append(loperator[i]) hs = np.zeros([nsite, nsite]) hs[0, 1] = 40 hs[1, 0] = 40 hs[1, 2] = 10 hs[2, 1] = 10 hs[2, 3] = 40 hs[3, 2] = 40 hs[3, 4] = 10 hs[4, 3] = 10 hs[4, 5] = 40 hs[5, 4] = 40 hs[5, 6] = 10 hs[6, 5] = 10 hs[6, 7] = 40 hs[7, 6] = 40 hs[7, 8] = 10 hs[8, 7] = 10 hs[8, 9] = 40 hs[9, 8] = 40 sys_param = { "HAMILTONIAN": np.array(hs, dtype=np.complex128), "GW_SYSBATH": gw_sysbath, "L_HIER": lop_list, "L_NOISE1": lop_list, "ALPHA_NOISE1": bcf_exp, "PARAM_NOISE1": gw_sysbath, } eom_param = {"EQUATION_OF_MOTION": "NORMALIZED NONLINEAR"} integrator_param = { "INTEGRATOR": "RUNGE_KUTTA", "INCHWORM": False, "INCHWORM_MIN": 5, } psi_0 = np.array([0.0] * nsite, dtype=np.complex) psi_0[5] = 1.0 psi_0 = psi_0 / np.linalg.norm(psi_0) hops_ad = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 2}, eom_param=eom_param, integration_param=integrator_param, ) hops_ad.make_adaptive(1e-3, 1e-3) hops_ad.initialize(psi_0) z_step = np.zeros(10) state_update, _ = hops_ad.basis.define_basis(hops_ad.phi, 2.0, z_step) # initial state state_new, state_stable, state_bound = state_update known_new = [4, 5, 6] assert state_new == known_new known_stable = [4, 5, 6] assert tuple(state_stable) == tuple(known_stable) known_bound = [] assert np.array_equal(state_bound, known_bound) # state after propagation hops_ad.propagate(10, 2) state_update, _ = hops_ad.basis.define_basis(hops_ad.phi, 2.0, z_step) state_new, state_stable, state_bound = state_update known_new = [3, 4, 5, 6, 7] assert state_new == known_new known_stable = [4, 5, 6] assert tuple(state_stable) == tuple(known_stable) known_bound = [3, 7] assert np.array_equal(state_bound, known_bound)
def test_store_step(): """ Test to make sure that store_step is properly storing propagated values """ hops = HOPS( sys_param, noise_param=noise_param, hierarchy_param=hier_param, eom_param=eom_param, integration_param=integrator_param, ) hops.make_adaptive() hops.initialize(psi_0) hops.propagate(2.0, 2.0) # time test time = hops.storage.t known_time = 2.0 assert time == known_time # t_axis test t_axis = hops.storage.t_axis known_t_axis = [0, 2.0] assert np.array_equal(t_axis, known_t_axis) # z_mem test z_mem = hops.storage.z_mem known_z_mem = [ 3.76011140e-03 + 0.0j, 1.88182635e-03 + 0.0j, 1.77699341e-08 + 0.0j, 8.88915173e-09 + 0.0j, ] np.testing.assert_almost_equal(z_mem, known_z_mem, 8) # aux storage False aux = hops.storage.aux known_aux = [] np.array_equal(aux, known_aux) # state list test state = hops.storage.state_list known_state = [[0, 1], [0, 1]] assert np.array_equal(state, known_state) # phi test phi = hops.storage.phi assert len(phi) == hops.n_hier * hops.n_state assert isinstance(phi, type(np.array([]))) assert isinstance(phi[0], np.complex128) # psi test psi_traj = hops.storage.psi_traj known_psi_traj = [ [1.0 + 0.0j, 0j], [0.999992832 - 0.00042642j, -4.06990909e-06 - 0.00376226j], ] np.testing.assert_allclose(psi_traj[0], np.array([1.0 + 0.0j, 0j])) np.testing.assert_allclose(psi_traj[1], hops.psi) phi_traj = hops.storage.phi_traj known_phi_traj = [] assert np.array_equal(phi_traj, known_phi_traj)
def test_error_sflux_hier(): """ test for the error introduced by losing flux within k from S_0 to S_0^C for each k in H_0 """ noise_param = { "SEED": 0, "MODEL": "FFT_FILTER", "TLEN": 250.0, # Units: fs "TAU": 1.0, # Units: fs } nsite = 10 e_lambda = 20.0 gamma = 50.0 temp = 140.0 (g_0, w_0) = bcf_convert_sdl_to_exp(e_lambda, gamma, 0.0, temp) loperator = np.zeros([10, 10, 10], dtype=np.float64) gw_sysbath = [] lop_list = [] for i in range(nsite): loperator[i, i, i] = 1.0 gw_sysbath.append([g_0, w_0]) lop_list.append(sp.sparse.coo_matrix(loperator[i])) gw_sysbath.append([-1j * np.imag(g_0), 500.0]) lop_list.append(loperator[i]) hs = np.zeros([nsite, nsite]) hs[0, 1] = 40 hs[1, 0] = 40 hs[1, 2] = 10 hs[2, 1] = 10 hs[2, 3] = 40 hs[3, 2] = 40 hs[3, 4] = 10 hs[4, 3] = 10 hs[4, 5] = 40 hs[5, 4] = 40 hs[5, 6] = 10 hs[6, 5] = 10 hs[6, 7] = 40 hs[7, 6] = 40 hs[7, 8] = 10 hs[8, 7] = 10 hs[8, 9] = 40 hs[9, 8] = 40 sys_param = { "HAMILTONIAN": np.array(hs, dtype=np.complex128), "GW_SYSBATH": gw_sysbath, "L_HIER": lop_list, "L_NOISE1": lop_list, "ALPHA_NOISE1": bcf_exp, "PARAM_NOISE1": gw_sysbath, } eom_param = {"EQUATION_OF_MOTION": "NORMALIZED NONLINEAR"} integrator_param = { "INTEGRATOR": "RUNGE_KUTTA", "INCHWORM": False, "INCHWORM_MIN": 5, } psi_0 = np.array([0.0] * nsite, dtype=np.complex) psi_0[5] = 1.0 psi_0 = psi_0 / np.linalg.norm(psi_0) hops_ad = HOPS( sys_param, noise_param=noise_param, hierarchy_param={"MAXHIER": 2}, eom_param=eom_param, integration_param=integrator_param, ) hops_ad.make_adaptive(1e-3, 1e-3) hops_ad.initialize(psi_0) E2_flux_state = hops_ad.basis.error_sflux_hier(hops_ad.phi, [4, 5, 6]) known_error = [0, 0, 0] assert np.allclose(E2_flux_state, known_error) hops_ad.propagate(10, 2) E2_flux_state = hops_ad.basis.error_sflux_hier(hops_ad.phi, [4, 5, 6]) known_error = [ 2.10004255e-04, 2.50146052e-06, 5.28986969e-05, 9.14077348e-06, 5.32245330e-05, 5.17421294e-05, 2.33186603e-05, 8.56003704e-06, 3.53943880e-07, 3.25690823e-06, 1.98318688e-05, 1.95396184e-05 ] assert np.allclose(E2_flux_state, known_error)