subroutine result_irecv(result, comm, source, tag, req)
!! Receive calculation result over MPI (non-blocking)
!! Receives SCF energy (non-blocking) and other components (blocking)
type(calculation_result_t), intent(inout) :: result
type(comm_t), intent(in) :: comm
integer, intent(in) :: source, tag
type(request_t), intent(out) :: req
type(MPI_Status) :: status
! Receive SCF energy (non-blocking)
call irecv(comm, result%energy%scf, source, tag, req)
! Receive other energy components (blocking to avoid needing multiple request handles)
call recv(comm, result%energy%mp2%ss, source, tag, status)
call recv(comm, result%energy%mp2%os, source, tag, status)
call recv(comm, result%energy%cc%singles, source, tag, status)
call recv(comm, result%energy%cc%doubles, source, tag, status)
call recv(comm, result%energy%cc%triples, source, tag, status)
result%has_energy = .true.
! Receive fragment metadata
call recv(comm, result%distance, source, tag, status)
! Receive gradient flag and data (blocking to avoid needing multiple request handles)
call recv(comm, result%has_gradient, source, tag, status)
if (result%has_gradient) then
! Receive allocatable gradient array (MPI lib handles allocation)
call recv(comm, result%gradient, source, tag, status)
end if
! Receive Hessian flag and data (blocking to avoid needing multiple request handles)
call recv(comm, result%has_hessian, source, tag, status)
if (result%has_hessian) then
! Receive allocatable Hessian array (MPI lib handles allocation)
call recv(comm, result%hessian, source, tag, status)
end if
! Receive dipole flag and data (blocking to avoid needing multiple request handles)
call recv(comm, result%has_dipole, source, tag, status)
if (result%has_dipole) then
! Receive allocatable dipole array (MPI lib handles allocation)
call recv(comm, result%dipole, source, tag, status)
end if
! Receive dipole derivatives flag and data (blocking to avoid needing multiple request handles)
call recv(comm, result%has_dipole_derivatives, source, tag, status)
if (result%has_dipole_derivatives) then
! Receive allocatable dipole derivatives array (MPI lib handles allocation)
call recv(comm, result%dipole_derivatives, source, tag, status)
end if
end subroutine result_irecv