def test_product_trace_nonsymmetric(self): ref = cache.refstate["cn_sto3g"] dipx_mo = ref.operators.electric_dipole[0] mp2diff_mo = adcc.LazyMp(ref).mp2_diffdm mp2diff_nosym = OneParticleOperator(ref.mospaces, is_symmetric=False) mp2diff_nosym.set_block("o1o1", mp2diff_mo["o1o1"]) mp2diff_nosym.set_block("o1v1", mp2diff_mo["o1v1"]) mp2diff_nosym.set_block("v1v1", mp2diff_mo["v1v1"]) mp2diff_nosym.set_block("v1o1", zeros_like(mp2diff_mo["o1v1"].transpose())) mp2diff_ao = mp2diff_nosym.to_ao_basis(ref) mp2a = mp2diff_ao[0].to_ndarray() mp2b = mp2diff_ao[1].to_ndarray() dipx_ao = ref.operators.provider_ao.electric_dipole[0] dipx_ref = np.sum(mp2a * dipx_ao) + np.sum(mp2b * dipx_ao) oo = np.sum(mp2diff_nosym["o1o1"].to_ndarray() * dipx_mo["o1o1"].to_ndarray()) ov = np.sum(mp2diff_nosym["o1v1"].to_ndarray() * dipx_mo["o1v1"].to_ndarray()) vo = np.sum(mp2diff_nosym["v1o1"].to_ndarray() * dipx_mo["o1v1"].to_ndarray().T) vv = np.sum(mp2diff_nosym["v1v1"].to_ndarray() * dipx_mo["v1v1"].to_ndarray()) dipx_np = oo + ov + vo + vv assert dipx_np == approx(product_trace(mp2diff_nosym, dipx_mo)) assert product_trace(mp2diff_nosym, dipx_mo) == approx(dipx_ref) assert product_trace(dipx_mo, mp2diff_nosym) == approx(dipx_ref)
def test_product_trace_both_nonsymmetric(self): ref = cache.refstate["cn_sto3g"] dipx_mo = ref.operators.electric_dipole[0] mp2diff_mo = adcc.LazyMp(ref).mp2_diffdm mp2diff_nosym = OneParticleOperator(ref.mospaces, is_symmetric=False) dipx_nosym = OneParticleOperator(ref.mospaces, is_symmetric=False) mp2diff_nosym.oo = mp2diff_mo.oo mp2diff_nosym.ov = mp2diff_mo.ov mp2diff_nosym.vv = mp2diff_mo.vv mp2diff_nosym.vo = zeros_like(mp2diff_mo.ov.transpose()) mp2diff_ao = mp2diff_nosym.to_ao_basis(ref) dipx_nosym.oo = dipx_mo.oo dipx_nosym.ov = dipx_mo.ov dipx_nosym.vv = dipx_mo.vv dipx_nosym.vo = zeros_like(dipx_mo.ov.transpose()) dipx_ao = dipx_nosym.to_ao_basis(ref) mp2a = mp2diff_ao[0].to_ndarray() mp2b = mp2diff_ao[1].to_ndarray() dipxa = dipx_ao[0].to_ndarray() dipxb = dipx_ao[1].to_ndarray() dipx_ref = np.sum(mp2a * dipxa) + np.sum(mp2b * dipxb) oo = np.sum(mp2diff_nosym.oo.to_ndarray() * dipx_nosym.oo.to_ndarray()) ov = np.sum(mp2diff_nosym.ov.to_ndarray() * dipx_nosym.ov.to_ndarray()) vo = np.sum(mp2diff_nosym.vo.to_ndarray() * dipx_nosym.vo.to_ndarray()) vv = np.sum(mp2diff_nosym.vv.to_ndarray() * dipx_nosym.vv.to_ndarray()) dipx_np = oo + ov + vo + vv assert dipx_np == approx(product_trace(mp2diff_nosym, dipx_nosym)) assert product_trace(mp2diff_nosym, dipx_nosym) == approx(dipx_ref) assert product_trace(dipx_nosym, mp2diff_nosym) == approx(dipx_ref)
def test_product_trace_symmetric(self): ref = cache.refstate["h2o_sto3g"] dipx_mo = ref.operators.electric_dipole[0] mp2diff_mo = adcc.LazyMp(ref).mp2_diffdm mp2diff_ao = mp2diff_mo.to_ao_basis(ref) mp2a = mp2diff_ao[0].to_ndarray() mp2b = mp2diff_ao[1].to_ndarray() dipx_ao = ref.operators.provider_ao.electric_dipole[0] dipx_ref = np.sum(mp2a * dipx_ao) + np.sum(mp2b * dipx_ao) oo = np.sum(mp2diff_mo.oo.to_ndarray() * dipx_mo.oo.to_ndarray()) ov = 2.0 * np.sum(mp2diff_mo.ov.to_ndarray() * dipx_mo.ov.to_ndarray()) vv = np.sum(mp2diff_mo.vv.to_ndarray() * dipx_mo.vv.to_ndarray()) dipx_np = oo + ov + vv assert dipx_np == approx(product_trace(mp2diff_mo, dipx_mo)) assert product_trace(mp2diff_mo, dipx_mo) == approx(dipx_ref) assert product_trace(dipx_mo, mp2diff_mo) == approx(dipx_ref)
matrix, rhs=rhs, x0=x0, callback=default_print, Pinv=preconditioner, conv_tol=1e-6, explicit_symmetrisation=explicit_symmetrisation ) response.append(res) for mu in range(3): for nu in range(mu, 3): tdm_mu_f = compute_state2state_optdm( "adc2", matrix.ground_state, response[mu].solution, state.excitation_vectors[f] ) tdm_nu_f = compute_state2state_optdm( "adc2", matrix.ground_state, response[nu].solution, state.excitation_vectors[f] ) # compute the matrix element S[f, mu, nu] = ( product_trace(tdm_mu_f, dips[nu]) + product_trace(tdm_nu_f, dips[mu]) ) S[f, nu, mu] = S[f, mu, nu] print("Two-Photon Matrix for state", f) print(S[f]) delta = 1.0 / 15.0 * ( np.einsum('mm,vv->', S[f], S[f]) + np.einsum('mv,mv->', S[f], S[f]) + np.einsum('mv,vm->', S[f], S[f]) ) print("TPA Cross section [a.u.]: {:.4f}".format(delta)) np.testing.assert_allclose(6.5539, delta, atol=1e-4)
for mu in range(3): rhs = rhss[mu] x0 = preconditioner.apply(rhs) res = conjugate_gradient( matrix, rhs=rhs, x0=x0, callback=default_print, Pinv=preconditioner, conv_tol=1e-6, explicit_symmetrisation=explicit_symmetrisation) response.append(res) for mu in range(3): for nu in range(mu, 3): tdm_mu_f = state2state_transition_dm("adc2", matrix.ground_state, response[mu].solution, state.excitation_vector[f]) tdm_nu_f = state2state_transition_dm("adc2", matrix.ground_state, response[nu].solution, state.excitation_vector[f]) # compute the matrix element S[f, mu, nu] = (product_trace(tdm_mu_f, dips[nu]) + product_trace(tdm_nu_f, dips[mu])) S[f, nu, mu] = S[f, mu, nu] print("Two-Photon Matrix for state", f) print(S[f]) delta = 1.0 / 15.0 * (np.einsum('mm,vv->', S[f], S[f]) + np.einsum( 'mv,mv->', S[f], S[f]) + np.einsum('mv,vm->', S[f], S[f])) print("TPA Cross section [a.u.]: {:.4f}".format(delta)) np.testing.assert_allclose(6.5539, delta, atol=1e-4)