Source code for sft_wick.propagators

"""Propagator contraction rules for MSR field theory.

Defines how pairs of field operators contract:
  <phi_i(x) phi_j(x')>_{S_0} = C_{ij}(x, x')
  <phi_i(x) psi_j(x')>_{S_0} = R_{ij}(x, x')
  <psi_i(x) psi_j(x')>_{S_0} = 0
"""

from __future__ import annotations

from typing import Optional

from .expressions import Propagator
from .fields import FieldOperator, FieldType


[docs] def contract_pair( op1: FieldOperator, op2: FieldOperator, ito: bool = True, ) -> Optional[Propagator]: r"""Contract two field operators and return the propagator, or None if it vanishes. Convention for R: physical field index/position is always on the left. R_{ij}(x, x') = <phi_i(x) psi_j(x')>_{S_0} Args: op1: First field operator. op2: Second field operator. ito: If ``True``, the Itô prescription :math:`\Theta(0)=0` is applied: the response propagator vanishes at equal spatial points, i.e. :math:`R(x,x)=0`. This eliminates diagrams with equal-point response contractions (e.g. intra-vertex tadpoles in local vertices). Returns: A :class:`~sft_wick.expressions.Propagator`, or ``None`` if the contraction vanishes. """ t1, t2 = op1.field_type, op2.field_type if t1 == FieldType.RESPONSE and t2 == FieldType.RESPONSE: return None if t1 == FieldType.PHYSICAL and t2 == FieldType.PHYSICAL: return Propagator( kind="C", index_left=op1.component_index, index_right=op2.component_index, spatial_left=op1.spatial_arg, spatial_right=op2.spatial_arg, ) if t1 == FieldType.PHYSICAL and t2 == FieldType.RESPONSE: if ito and op1.spatial_arg == op2.spatial_arg: return None return Propagator( kind="R", index_left=op1.component_index, index_right=op2.component_index, spatial_left=op1.spatial_arg, spatial_right=op2.spatial_arg, ) # t1 == RESPONSE, t2 == PHYSICAL: canonical order puts phi first if ito and op1.spatial_arg == op2.spatial_arg: return None return Propagator( kind="R", index_left=op2.component_index, index_right=op1.component_index, spatial_left=op2.spatial_arg, spatial_right=op1.spatial_arg, )