diff --git a/SeQuant/core/eval/eval_node.hpp b/SeQuant/core/eval/eval_node.hpp index 2be333062a..2e645820c1 100644 --- a/SeQuant/core/eval/eval_node.hpp +++ b/SeQuant/core/eval/eval_node.hpp @@ -114,9 +114,16 @@ struct Flops { if (n->op_type() == EvalOp::Product // && n.left()->is_tensor() // && n.right()->is_tensor()) { - auto const idx_count = ContractedIndexCount{n}; - auto c = AsyCost{idx_count.unique_occs(), idx_count.unique_virts()}; - return idx_count.is_outerpod() ? c : 2 * c; + if (n->is_tensor()) { + auto const idx_count = ContractedIndexCount{n}; + auto c = AsyCost{idx_count.unique_occs(), idx_count.unique_virts()}; + return idx_count.is_outerpod() ? c : 2 * c; + } else { // full contraction to scalar + SEQUANT_ASSERT(n->is_scalar()); + SEQUANT_ASSERT(occ_virt(n.left()->as_tensor()) == + occ_virt(n.right()->as_tensor())); + return 2 * AsyCost{occ_virt(n.left()->as_tensor())}; + } } else if (n->is_tensor()) { // scalar times a tensor // or a tensor plus a tensor diff --git a/tests/unit/test_eval_node.cpp b/tests/unit/test_eval_node.cpp index 84b8290a93..4b742d36a8 100644 --- a/tests/unit/test_eval_node.cpp +++ b/tests/unit/test_eval_node.cpp @@ -276,6 +276,13 @@ TEST_CASE("eval_node", "[EvalNode]") { auto const np3 = eval_node(p3); REQUIRE(asy_cost(np3) == AsyCost{2, 2, 1} + AsyCost{2, 3, 1}); + // full contraction to scalar: cc energy-like expression + auto const p_e = parse_expr_antisymm( + L"f_{i1}^{a1} * t_{a1}^{i1} + g_{i1,i2}^{a1,a2} * t_{a1,a2}^{i1,i2}"); + auto const n_e = eval_node(p_e); + REQUIRE(n_e->is_scalar()); + REQUIRE(asy_cost(n_e) == 2 * AsyCost{2, 2} + 2 * AsyCost{1, 1}); + #if 0 auto const s1 = parse_expr(L"I{i1,i2;a1,a2} + I{i1,i2;a1,a2}", Symmetry::Symm);