Task: Fix CCSD two-particle density matrix for complex orbitals (pyscf/pyscf#2531)

org: pyscf
repo: pyscf
pr_number: 2531
issue_title: Fix CCSD two-particle density matrix for complex orbitals
issue_body: * Fix #2519 
* Improve the doc-strings for two-particle density matrix functions.
resolved_issues: number: 2519
title: Incorrect conjugation in 2RDM transformations
body: PySCF typically uses the following conventions for DMs
```
dm1[p, q] = <q* p>
dm2[p, q, r, s] = <p* r* s q>
```

From Helgaker (3.2), when transforming operators under unitary $U$, the annihilation operator transforms under the conjugate $U^*$, and the creation operator transforms under $U$. This means that following the PySCF conventions, the 1RDM transforms as the Hamiltonian does i.e.
```python
dm1_ao = einsum("ij,pi,qj->pq", dm1_mo, c, c.conj())
```
but the 2RDM should transform as
```python
dm2_ao = einsum("ijkl,pi,qj,rk,sl->pqrs", dm2_mo, c.conj(), c, c.conj(), c)
```
whereas in PySCF the 2RDM is also assumed to transform as the Hamiltonian (the conjugations are reversed):
https://github.com/pyscf/pyscf/blob/2c7f7625fd2719b8f3e9715e40c3937cab65c06e/pyscf/cc/ccsd_rdm.py#L379-L381

This can be verified by trying to recover correlated energies using the RDMs in the AO basis via `ao_repr=True`, which fails, but works with the reverse transformation. See the following script for an example:
https://gist.github.com/obackhouse/855724a176c7f9cad580dc2d39e7c63d
We're aware in this case that the coefficients are not actually a unitary, but this is the best way I could find to show this as an issue in PySCF, and the issue seems to apply at least to the MO->AO transformation.

I am happy to fix but wanted to check if we are missing something first?

Reference solution:
fix_patch: diff --git a/pyscf/cc/ccsd_rdm.py b/pyscf/cc/ccsd_rdm.py
index de1b38f2b4..9353dcf3fe 100644
--- a/pyscf/cc/ccsd_rdm.py
+++ b/pyscf/cc/ccsd_rdm.py
@@ -377,8 +377,13 @@ def _make_rdm2(mycc, d1, d2, with_dm1=True, with_frozen=True, ao_repr=False):
 
 
 def _rdm2_mo2ao(dm2, mo):
+    '''
+    Back transform the two-particle density matrices to AO representation, where
+    the dm2 is defined in accordance with the chemist's ERI notation:
+    E = einsum('pqrs,pqrs', eri, rdm2)
+    '''
     mo_C = mo.conj()
-    return lib.einsum('ijkl,pi,qj,rk,sl->pqrs', dm2, mo, mo_C, mo, mo_C)
+    return lib.einsum('ijkl,pi,qj,rk,sl->pqrs', dm2, mo_C, mo, mo_C, mo)
 
 
 if __name__ == '__main__':
diff --git a/pyscf/cc/uccsd_rdm.py b/pyscf/cc/uccsd_rdm.py
index 7e096973f0..8c2bada6ee 100644
--- a/pyscf/cc/uccsd_rdm.py
+++ b/pyscf/cc/uccsd_rdm.py
@@ -625,8 +625,8 @@ def _make_rdm2(mycc, d1, d2, with_dm1=True, with_frozen=True, ao_repr=False):
 
 
 def _dm2ab_mo2ao(dm2, mo_a, mo_b):
-    return lib.einsum('ijkl,pi,qj,rk,sl->pqrs', dm2, mo_a, mo_a.conj(),
-                      mo_b, mo_b.conj())
+    return lib.einsum('ijkl,pi,qj,rk,sl->pqrs', dm2, mo_a.conj(), mo_a,
+                      mo_b.conj(), mo_b)
 
 
 if __name__ == '__main__':
diff --git a/pyscf/scf/hf.py b/pyscf/scf/hf.py
index 645cfee1f4..c3f30d93eb 100644
--- a/pyscf/scf/hf.py
+++ b/pyscf/scf/hf.py
@@ -853,6 +853,16 @@ def make_rdm1(mo_coeff, mo_occ, **kwargs):
 def make_rdm2(mo_coeff, mo_occ, **kwargs):
     '''Two-particle density matrix in AO representation
 
+    NOTE the indices of the two-particle density matrix is ordered to
+
+    dm2[p,q,r,s] = <q^+ s^+ r p>.
+
+    HF energy can be computed
+    E = einsum('pq,qp', hcore, 1pdm) + einsum('pqrs,pqrs', eri, 2pdm) / 2
+    where h1[p,q] = <p|h|q> and eri[p,q,r,s] = (pq|rs)
+to make the density matrix consistent with the density matrix obtained
+    from post-HF methods,
+
     Args:
         mo_coeff : 2D ndarray
             Orbital coefficients. Each column is one orbital.
diff --git a/pyscf/tdscf/_lr_eig.py b/pyscf/tdscf/_lr_eig.py
index 28beab7ffd..0eaa964bf5 100644
--- a/pyscf/tdscf/_lr_eig.py
+++ b/pyscf/tdscf/_lr_eig.py
@@ -524,10 +524,7 @@ def real_eig(aop, x0, precond, tol_residual=1e-5, nroots=1, x0sym=None, pick=Non
     assert pick is None
     assert callable(precond)
 
-    if isinstance(verbose, logger.Logger):
-        log = verbose
-    else:
-        log = logger.Logger(sys.stdout, verbose)
+    log = logger.new_logger(verbose)
 
     assert x0.ndim == 2
     A_size = x0.shape[1] // 2