12 #include <bagel_clover.h>
21 XMLWriter&
operator<<(XMLWriter& xml,
const PrimitiveClovTriang&
d)
23 xml.openTag(
"PrimClovTriang");
25 XMLWriterAPI::AttributeList alist;
28 for(
int i=0;
i < 2; ++
i)
30 for(
int j=0;
j < 2*Nc; ++
j)
33 alist.push_back(XMLWriterAPI::Attribute(
"block",
i));
34 alist.push_back(XMLWriterAPI::Attribute(
"col",
j));
36 xml.openTag(
"elem", alist);
44 for(
int i=0;
i < 2; ++
i)
46 for(
int j=0;
j < 2*Nc*Nc-Nc; ++
j)
49 alist.push_back(XMLWriterAPI::Attribute(
"block",
i));
50 alist.push_back(XMLWriterAPI::Attribute(
"col",
j));
52 xml.openTag(
"elem", alist);
65 void read(XMLReader& xml,
const std::string& path, PrimitiveClovTriang& param)
70 void write(XMLWriter& xml,
const std::string& path,
const PrimitiveClovTriang& param)
87 catch( std::bad_alloc ) {
95 catch( std::bad_alloc ) {
96 QDPIO::cerr <<
"Failed to allocate the tri_diag" << std::endl << std::flush ;
106 catch( std::bad_alloc ) {
114 catch( std::bad_alloc ) {
115 QDPIO::cerr <<
"Failed to allocate the tri_off_diag" << std::endl << std::flush ;
126 QDP::Allocator::theQDPAllocator::Instance().free(
tri_diag);
130 QDP::Allocator::theQDPAllocator::Instance().free(
tri_off_diag);
141 fbc = fs->getFermBC();
145 if (
fbc.operator->() == 0)
147 QDPIO::cerr <<
"BAGELCloverTerm: error: fbc is null" << std::endl;
169 multi1d<LatticeColorMatrix> f;
174 for(
int i=0;
i < rb.numSubsets();
i++) {
181 LatticeFermion res1=
zero;
182 LatticeFermion res2=
zero;
187 LatticeFermion diff=res1-res2;
188 XMLFileWriter fred(
"fred");
190 write(fred,
"diff", diff);
193 QDPIO::cout <<
"sqrt( norm2( diff))= " << sqrt(norm2(diff)) << std::endl << std::flush;
209 fbc = fs->getFermBC();
213 if (
fbc.operator->() == 0) {
214 QDPIO::cerr <<
"BAGELCloverTerm: error: fbc is null" << std::endl;
242 for(
int i=0;
i < rb.numSubsets();
i++) {
251 for(
int site=0; site < Layout::sitesOnNode(); site++) {
253 for(
int comp=0; comp< 6; comp++) {
256 for(
int comp=0; comp < 15; comp++) {
351 LatticeColorMatrix f0;
352 LatticeColorMatrix
f1;
353 LatticeColorMatrix
f2;
354 LatticeColorMatrix
f3;
355 LatticeColorMatrix
f4;
356 LatticeColorMatrix
f5;
358 const int nodeSites = QDP::Layout::sitesOnNode();
418 for(
int site = 0; site < nodeSites; ++site)
421 for(
int jj = 0; jj < 2; jj++)
423 for(
int ii = 0; ii < 2*Nc; ii++)
425 tri_diag[site][jj][ii] = diag_mass.elem().elem().elem();
434 for(
int site = 0; site < nodeSites; ++site)
436 RComplex<REAL> E_minus;
437 RComplex<REAL> B_minus;
438 RComplex<REAL> ctmp_0;
439 RComplex<REAL> ctmp_1;
440 RScalar<REAL> rtmp_0;
441 RScalar<REAL> rtmp_1;
443 for(
int i = 0;
i < Nc; ++
i)
447 ctmp_0 =
f5.elem(site).elem().elem(
i,
i);
448 ctmp_0 -= f0.elem(site).elem().elem(
i,
i);
449 rtmp_0 = imag(ctmp_0);
458 ctmp_1 =
f5.elem(site).elem().elem(
i,
i);
459 ctmp_1 += f0.elem(site).elem().elem(
i,
i);
460 rtmp_1 = imag(ctmp_1);
470 for(
int i = 1;
i < Nc; ++
i)
472 for(
int j = 0;
j <
i; ++
j)
475 int elem_tmp = (
i+Nc)*(
i+Nc-1)/2 +
j+Nc;
479 ctmp_0 = f0.elem(site).elem().elem(
i,
j);
480 ctmp_0 -=
f5.elem(site).elem().elem(
i,
j);
489 ctmp_1 =
f5.elem(site).elem().elem(
i,
j);
490 ctmp_1 += f0.elem(site).elem().elem(
i,
j);
500 for(
int i = 0;
i < Nc; ++
i)
502 for(
int j = 0;
j < Nc; ++
j)
511 E_minus = timesI(
f2.elem(site).elem().elem(
i,
j));
512 E_minus +=
f4.elem(site).elem().elem(
i,
j);
516 B_minus = timesI(
f3.elem(site).elem().elem(
i,
j));
517 B_minus -=
f1.elem(site).elem().elem(
i,
j);
563 QDPIO::cout <<
"Error: YOu have not done the Cholesky.on this operator on this subset" << std::endl;
564 QDPIO::cout <<
"You sure you shouldn't be asking invclov?" << std::endl;
582 tr_log_diag[rb[
cb]] =
zero;
588 for(
int ssite=0; ssite < rb[
cb].numSiteTable(); ++ssite)
590 int site = rb[
cb].siteTable()[ssite];
592 int site_neg_logdet=0;
599 RScalar<REAL> inv_d[8] QDP_ALIGN16;
600 RComplex<REAL> inv_offd[16] QDP_ALIGN16;
601 RComplex<REAL> v[8] QDP_ALIGN16;
602 RScalar<REAL> diag_g[8] QDP_ALIGN16;
605 for(
int i=0;
i < N;
i++) {
608 for(
int i=0;
i < 15;
i++) {
612 for(
int j=0;
j < N; ++
j) {
621 for(
int i=0;
i <
j;
i++) {
624 RComplex<REAL> A_ii = cmplx( inv_d[
i], zip );
636 v[
j] = cmplx(inv_d[
j],zip);
638 for(
int k=0;
k <
j;
k++) {
639 int elem_jk =
j*(
j-1)/2 +
k;
640 v[
j] -= inv_offd[elem_jk]*v[
k];
649 inv_d[
j] = real( v[
j] );
663 for(
int k=
j+1;
k < N;
k++) {
664 int elem_kj =
k*(
k-1)/2 +
j;
665 for(
int l=0;
l <
j;
l++) {
666 int elem_kl =
k*(
k-1)/2 +
l;
667 inv_offd[elem_kj] -= inv_offd[elem_kl] * v[
l];
669 inv_offd[elem_kj] /= v[
j];
675 one.elem() = (REAL)1;
677 for(
int i=0;
i < N;
i++) {
678 diag_g[
i] =
one/inv_d[
i];
684 tr_log_diag.elem(site).elem().elem().elem() += log(fabs(inv_d[
i].elem()));
687 if( inv_d[
i].elem() < 0 ) {
706 for(
int k = 0;
k < N; ++
k)
708 for(
int i = 0;
i <
k; ++
i) {
715 v[
k] = cmplx(diag_g[
k],zip);
717 for(
int i =
k+1;
i < N; ++
i) {
720 for(
int j =
k;
j <
i; ++
j) {
736 for(
int i = N-2; (int)
i >= (
int)
k; --
i) {
737 for(
int j =
i+1;
j < N; ++
j) {
745 inv_d[
k] = real(v[
k]);
746 for(
int i =
k+1;
i < N; ++
i)
748 int elem_ik =
i*(
i-1)/2+
k;
749 inv_offd[elem_ik] = v[
i];
755 for(
int i=0;
i < N;
i++) {
758 for(
int i=0;
i < 15;
i++) {
763 if( site_neg_logdet != 0 ) {
765 std::cout <<
"WARNING: Odd number of negative terms in Clover DET ("
766 << site_neg_logdet<<
") at site: " << site << std::endl;
802 for(
int ssite=0; ssite < rb[
cb].numSiteTable(); ++ssite)
804 int site = rb[
cb].siteTable()[ssite];
809 multi1d< RScalar<REAL> > diag_g(
n);
810 multi1d< RComplex<REAL> > v1(
n);
819 for(
int s = 0;
s < 2; ++
s)
824 for(
int j = 0;
j <
n; ++
j)
832 for(
int i =
j+1;
i <
n; ++
i)
840 for(
int k = 0;
k <
j; ++
k)
842 int elem_ik = elem_jk;
844 for(
int i =
j;
i <
n; ++
i)
846 v1[
i] -= adj(invclov_off_diag[
s][elem_jk]) * invclov_off_diag[
s][elem_ik];
853 diag_g[
j] = real(v1[
j]);
858 if ( diag_g[
j].elem() > 0 )
860 lrtmp = log(diag_g[
j]);
865 std::cerr <<
"Clover term has negative diagonal element: "
866 <<
"diag_g[" <<
j <<
"]= " << diag_g[
j]
867 <<
" at site: " << site << std::endl;
871 tr_log_diag.elem(site).elem().elem() += lrtmp;
873 diag_g[
j] = sqrt(diag_g[
j]);
874 diag_g[
j] =
one / diag_g[
j];
878 for(
int i =
j+1;
i <
n; ++
i)
880 invclov_off_diag[
s][
elem_ij] = v1[
i] * diag_g[
j];
886 for(
int k = 0;
k <
n; ++
k)
888 for(
int i = 0;
i <
k; ++
i)
892 v1[
k] = cmplx(diag_g[
k],
zero);
894 for(
int i =
k+1;
i <
n; ++
i)
898 for(
int j =
k;
j <
i; ++
j)
904 v1[
i] =
sum * diag_g[
i];
908 v1[
n-1] = v1[
n-1] * diag_g[
n-1];
910 for(
int i =
n-2; (int)
i >= (
int)
k; --
i)
915 for(
int j =
i+1;
j <
n; ++
j)
920 v1[
i] =
sum * diag_g[
i];
924 invclov_diag[
s][
k] = real(v1[
k]);
926 int elem_ik = ((
k+1)*
k)/2+
k;
928 for(
int i =
k+1;
i <
n; ++
i)
930 invclov_off_diag[
s][elem_ik] = v1[
i];
937 for(
int s=0;
s < 2;
s++) {
938 for(
int i=0;
i < 6;
i++) {
941 for(
int i=0;
i < 15;
i++) {
981 if( rb[
cb].hasOrderedRep() ) {
984 int start = rb[
cb].start();
985 unsigned long n_sites=rb[
cb].siteTable().size();
988 unsigned long n_sites =1;
994 BAGELCloverFloat* chiptr = (BAGELCloverFloat *)&(
chi.elem(start).elem(0).elem(0).real());
995 const BAGELCloverFloat* psiptr = (
const BAGELCloverFloat *)&(
psi.elem(start).elem(0).elem(0).real());
996 const BAGELCloverFloat* offd = (
const BAGELCloverFloat *)&(
tri_off_diag[start][0][0].real());
997 const BAGELCloverFloat* diag = (
const BAGELCloverFloat *)&(
tri_diag[start][0][0].elem());
998 bagel_clover(diag, offd, psiptr, chiptr, n_sites);
1002 const multi1d<int>& tab = rb[
cb].siteTable();
1005 for(
int ssite=0; ssite < tab.size(); ++ssite) {
1007 int site = tab[ssite];
1008 unsigned long n_sites=1;
1012 BAGELCloverFloat* chiptr = (BAGELCloverFloat *)&(
chi.elem(site).elem(0).elem(0).real());
1013 const BAGELCloverFloat* psiptr = (
const BAGELCloverFloat *)&(
psi.elem(site).elem(0).elem(0).real());
1014 const BAGELCloverFloat* offd = (
const BAGELCloverFloat *)&(
tri_off_diag[site][0][0].real());
1015 const BAGELCloverFloat* diag = (
const BAGELCloverFloat *)&(
tri_diag[site][0][0].elem());
1016 bagel_clover(diag, offd, psiptr, chiptr, n_sites);
1053 RComplex<REAL>* cchi = (RComplex<REAL>*)&(
chi.elem(site).elem(0).elem(0));
1054 const RComplex<REAL>* ppsi = (
const RComplex<REAL>*)&(
psi.elem(site).elem(0).elem(0));
1057 cchi[ 0] =
tri_diag[site][0][ 0] * ppsi[ 0]
1064 cchi[ 1] =
tri_diag[site][0][ 1] * ppsi[ 1]
1071 cchi[ 2] =
tri_diag[site][0][ 2] * ppsi[ 2]
1078 cchi[ 3] =
tri_diag[site][0][ 3] * ppsi[ 3]
1085 cchi[ 4] =
tri_diag[site][0][ 4] * ppsi[ 4]
1092 cchi[ 5] =
tri_diag[site][0][ 5] * ppsi[ 5]
1099 cchi[ 6] =
tri_diag[site][1][ 0] * ppsi[ 6]
1106 cchi[ 7] =
tri_diag[site][1][ 1] * ppsi[ 7]
1113 cchi[ 8] =
tri_diag[site][1][ 2] * ppsi[ 8]
1120 cchi[ 9] =
tri_diag[site][1][ 3] * ppsi[ 9]
1127 cchi[10] =
tri_diag[site][1][ 4] * ppsi[10]
1134 cchi[11] =
tri_diag[site][1][ 5] * ppsi[11]
1186 if ( mat < 0 || mat > 15 )
1188 QDPIO::cerr << __func__ <<
": Gamma out of range: mat = " << mat << std::endl;
1200 for(
int ssite=0; ssite < rb[
cb].numSiteTable(); ++ssite)
1202 int site = rb[
cb].siteTable()[ssite];
1204 RComplex<REAL> lctmp0;
1205 RScalar<REAL> lr_zero0;
1206 RScalar<REAL> lrtmp0;
1210 for(
int i0 = 0; i0 < Nc; ++i0)
1213 lrtmp0 +=
tri_diag[site][0][i0+Nc];
1215 lrtmp0 +=
tri_diag[site][1][i0+Nc];
1216 B.elem(site).elem().elem(i0,i0) = cmplx(lrtmp0,lr_zero0);
1221 for(
int i0 = 1; i0 < Nc; ++i0)
1223 int elem_ijb0 = (i0+Nc)*(i0+Nc-1)/2 + Nc;
1225 for(
int j0 = 0; j0 < i0; ++j0)
1232 B.elem(site).elem().elem(j0,i0) = lctmp0;
1233 B.elem(site).elem().elem(i0,j0) = adj(lctmp0);
1249 for(
int ssite=0; ssite < rb[
cb].numSiteTable(); ++ssite)
1251 int site = rb[
cb].siteTable()[ssite];
1253 RComplex<REAL> lctmp3;
1254 RScalar<REAL> lr_zero3;
1255 RScalar<REAL> lrtmp3;
1259 for(
int i3 = 0; i3 < Nc; ++i3)
1264 lrtmp3 +=
tri_diag[site][1][i3+Nc];
1265 B.elem(site).elem().elem(i3,i3) = cmplx(lr_zero3,lrtmp3);
1270 for(
int i3 = 1; i3 < Nc; ++i3)
1272 int elem_ijb3 = (i3+Nc)*(i3+Nc-1)/2 + Nc;
1274 for(
int j3 = 0; j3 < i3; ++j3)
1281 B.elem(site).elem().elem(j3,i3) = timesI(adj(lctmp3));
1282 B.elem(site).elem().elem(i3,j3) = timesI(lctmp3);
1296 for(
int ssite=0; ssite < rb[
cb].numSiteTable(); ++ssite)
1298 int site = rb[
cb].siteTable()[ssite];
1300 RComplex<REAL> lctmp5;
1301 RScalar<REAL> lrtmp5;
1303 for(
int i5 = 0; i5 < Nc; ++i5)
1305 int elem_ij5 = (i5+Nc)*(i5+Nc-1)/2;
1307 for(
int j5 = 0; j5 < Nc; ++j5)
1309 int elem_ji5 = (j5+Nc)*(j5+Nc-1)/2 + i5;
1318 B.elem(site).elem().elem(i5,j5) = lctmp5;
1331 for(
int ssite=0; ssite < rb[
cb].numSiteTable(); ++ssite)
1333 int site = rb[
cb].siteTable()[ssite];
1335 RComplex<REAL> lctmp6;
1336 RScalar<REAL> lrtmp6;
1338 for(
int i6 = 0; i6 < Nc; ++i6)
1340 int elem_ij6 = (i6+Nc)*(i6+Nc-1)/2;
1342 for(
int j6 = 0; j6 < Nc; ++j6)
1344 int elem_ji6 = (j6+Nc)*(j6+Nc-1)/2 + i6;
1351 B.elem(site).elem().elem(i6,j6) = timesMinusI(lctmp6);
1364 for(
int ssite=0; ssite < rb[
cb].numSiteTable(); ++ssite)
1366 int site = rb[
cb].siteTable()[ssite];
1368 RComplex<REAL> lctmp9;
1369 RScalar<REAL> lrtmp9;
1371 for(
int i9 = 0; i9 < Nc; ++i9)
1373 int elem_ij9 = (i9+Nc)*(i9+Nc-1)/2;
1375 for(
int j9 = 0; j9 < Nc; ++j9)
1377 int elem_ji9 = (j9+Nc)*(j9+Nc-1)/2 + i9;
1384 B.elem(site).elem().elem(i9,j9) = timesI(lctmp9);
1397 for(
int ssite=0; ssite < rb[
cb].numSiteTable(); ++ssite)
1399 int site = rb[
cb].siteTable()[ssite];
1401 RComplex<REAL> lctmp10;
1402 RScalar<REAL> lrtmp10;
1404 for(
int i10 = 0; i10 < Nc; ++i10)
1406 int elem_ij10 = (i10+Nc)*(i10+Nc-1)/2;
1408 for(
int j10 = 0; j10 < Nc; ++j10)
1410 int elem_ji10 = (j10+Nc)*(j10+Nc-1)/2 + i10;
1417 B.elem(site).elem().elem(i10,j10) = lctmp10;
1431 for(
int ssite=0; ssite < rb[
cb].numSiteTable(); ++ssite)
1433 int site = rb[
cb].siteTable()[ssite];
1435 RComplex<REAL> lctmp12;
1436 RScalar<REAL> lr_zero12;
1437 RScalar<REAL> lrtmp12;
1441 for(
int i12 = 0; i12 < Nc; ++i12)
1444 lrtmp12 -=
tri_diag[site][0][i12+Nc];
1446 lrtmp12 +=
tri_diag[site][1][i12+Nc];
1447 B.elem(site).elem().elem(i12,i12) = cmplx(lr_zero12,lrtmp12);
1452 for(
int i12 = 1; i12 < Nc; ++i12)
1454 int elem_ijb12 = (i12+Nc)*(i12+Nc-1)/2 + Nc;
1456 for(
int j12 = 0; j12 < i12; ++j12)
1463 B.elem(site).elem().elem(i12,j12) = timesI(lctmp12);
1464 B.elem(site).elem().elem(j12,i12) = timesI(adj(lctmp12));
1476 QDPIO::cout <<
"BAD DEFAULT CASE HIT" << std::endl;
Primary include file for CHROMA library code.
void makeClov(const multi1d< LatticeColorMatrix > &f, const Real &diag_mass)
Create the clover term on cb.
void ldagdlinv(LatticeReal &tr_log_diag, int cb)
Invert the clover term on cb using LDL^\dagger decomp.
~BAGELCloverTerm()
Free the internals.
Real getCloverCoeff(int mu, int nu) const
Calculates Tr_D ( Gamma_mat L )
void apply(LatticeFermion &chi, const LatticeFermion &psi, enum PlusMinus isign, int cb) const
Handle< FermBC< T, P, Q > > fbc
const FermBC< T, P, Q > & getFermBC() const
Return the fermion BC object for this linear operator.
multi1d< LatticeColorMatrix > u
void create(Handle< FermState< T, P, Q > > fs, const CloverFermActParams ¶m_, const BAGELCloverTerm &from)
Create from another.
PrimitiveClovOffDiag * tri_off_diag
CloverFermActParams param
multi1d< bool > choles_done
PrimitiveClovDiag * tri_diag
void chlclovms(LatticeReal &log_diag, int cb)
Invert the clover term on cb using Cholesky decomp.
BAGELCloverTerm()
Empty constructor. Must use create later.
Double cholesDet(int cb) const
Computes the inverse of the term on cb using Cholesky.
void choles(int cb)
Computes the inverse of the term on cb using Cholesky.
void applySite(LatticeFermion &chi, const LatticeFermion &psi, enum PlusMinus isign, int site) const
Support class for fermion actions and linear operators.
Class for counted reference semantics.
Clover term linear operator.
void read(XMLReader &xml, const std::string &path, AsqtadFermActParams ¶m)
Read parameters.
void write(XMLWriter &xml, const std::string &path, const AsqtadFermActParams ¶m)
Writer parameters.
void block(LatticeColorMatrix &u_block, const multi1d< LatticeColorMatrix > &u, int mu, int bl_level, const Real &BlkAccu, int BlkMax, int j_decay)
Construct block links.
void triacntr(LatticeColorMatrix &B, int mat, int cb) const
Calculates Tr_D ( Gamma_mat L )
Calculates the antihermitian field strength tensor iF(mu,nu)
Asqtad Staggered-Dirac operator.
QDP::StandardOutputStream & operator<<(QDP::StandardOutputStream &s, const multi1d< int > &d)
QDP_error_exit("too many BiCG iterations", n_count, rsd_sq, cp, c, re_rvr, im_rvr, re_a, im_a, re_b, im_b)
push(xml_out,"Condensates")
multi1d< LatticeFermion > chi(Ncb)
RScalar< REAL > PrimitiveClovDiag[2][8]
Special structure used for triangular objects.
void mesField(multi1d< LatticeColorMatrixF > &f, const multi1d< LatticeColorMatrixF > &u)
Calculates the antihermitian field strength tensor iF(mu,nu)
RComplex< REAL > PrimitiveClovOffDiag[2][16]
multi1d< LatticeFermion > s(Ncb)
const T1 const T2 const T3 & f3
const T1 const T2 const T3 const T4 const T5 & f5
const T1 const T2 const T3 const T4 & f4
FloatingPoint< double > Double
Params for clover ferm acts.