25 #include "MPIchemps2.h" 28 void CheMPS2::Heff::addDiagram3Aand3D(
const int ikappa,
double * memS,
double * memHeff,
const Sobject * denS, TensorQ * Qleft, TensorL ** Lleft,
double * temp)
const{
30 int NL = denS->gNL(ikappa);
31 int TwoSL = denS->gTwoSL(ikappa);
32 int IL = denS->gIL(ikappa);
33 int N1 = denS->gN1(ikappa);
34 int N2 = denS->gN2(ikappa);
35 int TwoJ = denS->gTwoJ(ikappa);
36 int NR = denS->gNR(ikappa);
37 int TwoSR = denS->gTwoSR(ikappa);
38 int IR = denS->gIR(ikappa);
40 int theindex = denS->gIndex();
42 int TwoS2 = (N2==1)?1:0;
44 int dimR = denBK->
gCurrentDim(theindex+2,NR,TwoSR,IR);
45 int dimLup = denBK->
gCurrentDim(theindex,NL,TwoSL,IL);
48 for (
int TwoSLdown=TwoSL-1; TwoSLdown<=TwoSL+1; TwoSLdown+=2){
50 int dimLdown = denBK->
gCurrentDim(theindex, NL+1, TwoSLdown, ILdown);
53 int TwoJstart = ((TwoSR!=TwoSLdown) || (TwoS2==0)) ? 1 + TwoS2 : 0;
54 for (
int TwoJdown=TwoJstart; TwoJdown<=1+TwoS2; TwoJdown+=2){
55 if (abs(TwoSLdown-TwoSR)<=TwoJdown){
57 int memSkappa = denS->gKappa(NL+1,TwoSLdown,ILdown,1,N2,TwoJdown,NR,TwoSR,IR);
59 int fase =
phase(TwoSL+TwoSR+2+TwoS2);
60 double factor = sqrt((TwoJdown+1)*(TwoSLdown+1.0))*fase*
Wigner::wigner6j(TwoJdown,TwoS2,1,TwoSL,TwoSLdown,TwoSR);
64 double * BlockQ = Qleft->gStorage(NL,TwoSL,IL,NL+1,TwoSLdown,ILdown);
66 int size = dimLup * dimLdown;
67 dcopy_(&size, BlockQ, &inc, temp, &inc);
69 for (
int l_index=0; l_index<theindex; l_index++){
71 double alpha = Prob->
gMxElement(l_index,theindex,theindex,theindex);
72 double * BlockL = Lleft[theindex-1-l_index]->gStorage(NL,TwoSL,IL,NL+1,TwoSLdown,ILdown);
73 daxpy_(&size, &alpha, BlockL, &inc, temp, &inc);
77 dgemm_(¬r,¬r,&dimLup,&dimR,&dimLdown,&factor,temp,&dimLup,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
86 for (
int TwoSLdown=TwoSL-1; TwoSLdown<=TwoSL+1; TwoSLdown+=2){
87 if ((abs(TwoSLdown-TwoSR)<=TwoS2) && (TwoSLdown>=0)){
88 int dimLdown = denBK->
gCurrentDim(theindex, NL+1, TwoSLdown, ILdown);
89 int memSkappa = denS->gKappa(NL+1,TwoSLdown,ILdown,0,N2,TwoS2,NR,TwoSR,IR);
91 int fase =
phase(TwoSL+TwoSR+1+TwoS2);
92 double factor = sqrt((TwoSLdown+1)*(TwoJ+1.0))*fase*
Wigner::wigner6j(TwoS2,TwoJ,1,TwoSL,TwoSLdown,TwoSR);
95 double * BlockQ = Qleft->gStorage(NL,TwoSL,IL,NL+1,TwoSLdown,ILdown);
96 dgemm_(¬r,¬r,&dimLup,&dimR,&dimLdown,&factor,BlockQ,&dimLup,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
103 for (
int TwoSLdown=TwoSL-1;TwoSLdown<=TwoSL+1;TwoSLdown+=2){
105 int dimLdown = denBK->
gCurrentDim(theindex, NL-1, TwoSLdown, ILdown);
108 int TwoJstart = ((TwoSR!=TwoSLdown) || (TwoS2==0)) ? 1 + TwoS2 : 0;
109 for (
int TwoJdown=TwoJstart; TwoJdown<=1+TwoS2; TwoJdown+=2){
110 if (abs(TwoSLdown-TwoSR)<=TwoJdown){
112 int memSkappa = denS->gKappa(NL-1,TwoSLdown,ILdown,1,N2,TwoJdown,NR,TwoSR,IR);
114 int fase =
phase(TwoSLdown+TwoSR+1+TwoS2);
115 double factor = fase*sqrt((TwoSL+1)*(TwoJdown+1.0))*
Wigner::wigner6j(TwoJdown,TwoS2,1,TwoSL,TwoSLdown,TwoSR);
119 double * BlockQ = Qleft->gStorage(NL-1,TwoSLdown,ILdown,NL,TwoSL,IL);
120 dgemm_(&trans,¬r,&dimLup,&dimR,&dimLdown,&factor,BlockQ,&dimLdown,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
129 for (
int TwoSLdown=TwoSL-1;TwoSLdown<=TwoSL+1;TwoSLdown+=2){
130 if ((abs(TwoSLdown-TwoSR)<=TwoS2) && (TwoSLdown>=0)){
131 int dimLdown = denBK->
gCurrentDim(theindex, NL-1, TwoSLdown, ILdown);
132 int memSkappa = denS->gKappa(NL-1,TwoSLdown,ILdown,2,N2,TwoS2,NR,TwoSR,IR);
134 int fase =
phase(TwoSLdown+TwoSR+2+TwoS2);
135 double factor = fase*sqrt((TwoSL+1)*(TwoJ+1.0))*
Wigner::wigner6j(TwoS2,TwoJ,1,TwoSL,TwoSLdown,TwoSR);
140 double * BlockQ = Qleft->gStorage(NL-1,TwoSLdown,ILdown,NL,TwoSL,IL);
142 int size = dimLup * dimLdown;
143 dcopy_(&size, BlockQ, &inc, temp, &inc);
145 for (
int l_index=0; l_index<theindex; l_index++){
147 double alpha = Prob->
gMxElement(l_index,theindex,theindex,theindex);
148 double * BlockL = Lleft[theindex-1-l_index]->gStorage(NL-1,TwoSLdown,ILdown,NL,TwoSL,IL);
149 daxpy_(&size, &alpha, BlockL, &inc, temp, &inc);
153 dgemm_(&trans,¬r,&dimLup,&dimR,&dimLdown,&factor,temp,&dimLdown,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
161 void CheMPS2::Heff::addDiagram3Band3I(
const int ikappa,
double * memS,
double * memHeff,
const Sobject * denS, TensorQ * Qleft, TensorL ** Lleft,
double * temp)
const{
163 int NL = denS->gNL(ikappa);
164 int TwoSL = denS->gTwoSL(ikappa);
165 int IL = denS->gIL(ikappa);
166 int N1 = denS->gN1(ikappa);
167 int N2 = denS->gN2(ikappa);
168 int TwoJ = denS->gTwoJ(ikappa);
169 int NR = denS->gNR(ikappa);
170 int TwoSR = denS->gTwoSR(ikappa);
171 int IR = denS->gIR(ikappa);
173 int theindex = denS->gIndex();
175 int TwoS1 = (N1==1)?1:0;
177 int dimR = denBK->
gCurrentDim(theindex+2,NR,TwoSR,IR);
178 int dimLup = denBK->
gCurrentDim(theindex,NL,TwoSL,IL);
181 for (
int TwoSLdown=TwoSL-1; TwoSLdown<=TwoSL+1; TwoSLdown+=2){
183 int dimLdown = denBK->
gCurrentDim(theindex, NL+1, TwoSLdown, ILdown);
186 int TwoJstart = ((TwoSR!=TwoSLdown) || (TwoS1==0)) ? 1 + TwoS1 : 0;
187 for (
int TwoJdown=TwoJstart; TwoJdown<=1+TwoS1; TwoJdown+=2){
188 if (abs(TwoSLdown-TwoSR)<=TwoJdown){
190 int memSkappa = denS->gKappa(NL+1,TwoSLdown,ILdown,N1,1,TwoJdown,NR,TwoSR,IR);
192 int fase =
phase(TwoSL+TwoSR+3-TwoJdown);
193 double factor = sqrt((TwoJdown+1)*(TwoSLdown+1.0))*fase*
Wigner::wigner6j(TwoJdown,TwoS1,1,TwoSL,TwoSLdown,TwoSR);
197 double * BlockQ = Qleft->gStorage(NL,TwoSL,IL,NL+1,TwoSLdown,ILdown);
199 int size = dimLup * dimLdown;
200 dcopy_(&size, BlockQ, &inc, temp, &inc);
202 for (
int l_index=0; l_index<theindex; l_index++){
203 if (denBK->
gIrrep(l_index) == denBK->
gIrrep(theindex+1)){
204 double alpha = Prob->
gMxElement(l_index,theindex+1,theindex+1,theindex+1);
205 double * BlockL = Lleft[theindex-1-l_index]->gStorage(NL,TwoSL,IL,NL+1,TwoSLdown,ILdown);
206 daxpy_(&size, &alpha, BlockL, &inc, temp, &inc);
210 dgemm_(¬r,¬r,&dimLup,&dimR,&dimLdown,&factor,temp,&dimLup,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
219 for (
int TwoSLdown=TwoSL-1; TwoSLdown<=TwoSL+1; TwoSLdown+=2){
220 if ((abs(TwoSLdown-TwoSR)<=TwoS1) && (TwoSLdown>=0)){
221 int dimLdown = denBK->
gCurrentDim(theindex, NL+1, TwoSLdown, ILdown);
222 int memSkappa = denS->gKappa(NL+1,TwoSLdown,ILdown,N1,0,TwoS1,NR,TwoSR,IR);
224 int fase =
phase(TwoSL+TwoSR+2-TwoJ);
225 double factor = sqrt((TwoSLdown+1)*(TwoJ+1.0))*fase*
Wigner::wigner6j(TwoS1,TwoJ,1,TwoSL,TwoSLdown,TwoSR);
228 double * BlockQ = Qleft->gStorage(NL,TwoSL,IL,NL+1,TwoSLdown,ILdown);
229 dgemm_(¬r,¬r,&dimLup,&dimR,&dimLdown,&factor,BlockQ,&dimLup,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
236 for (
int TwoSLdown=TwoSL-1;TwoSLdown<=TwoSL+1;TwoSLdown+=2){
238 int dimLdown = denBK->
gCurrentDim(theindex, NL-1, TwoSLdown, ILdown);
241 int TwoJstart = ((TwoSR!=TwoSLdown) || (TwoS1==0)) ? 1 + TwoS1 : 0;
242 for (
int TwoJdown=TwoJstart; TwoJdown<=1+TwoS1; TwoJdown+=2){
243 if (abs(TwoSLdown-TwoSR)<=TwoJdown){
245 int memSkappa = denS->gKappa(NL-1,TwoSLdown,ILdown,N1,1,TwoJdown,NR,TwoSR,IR);
247 int fase =
phase(TwoSLdown+TwoSR+2-TwoJdown);
248 double factor = fase*sqrt((TwoSL+1)*(TwoJdown+1.0))*
Wigner::wigner6j(TwoJdown,TwoS1,1,TwoSL,TwoSLdown,TwoSR);
252 double * BlockQ = Qleft->gStorage(NL-1,TwoSLdown,ILdown,NL,TwoSL,IL);
253 dgemm_(&trans,¬r,&dimLup,&dimR,&dimLdown,&factor,BlockQ,&dimLdown,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
262 for (
int TwoSLdown=TwoSL-1;TwoSLdown<=TwoSL+1;TwoSLdown+=2){
263 if ((abs(TwoSLdown-TwoSR)<=TwoS1) && (TwoSLdown>=0)){
264 int dimLdown = denBK->
gCurrentDim(theindex, NL-1, TwoSLdown, ILdown);
265 int memSkappa = denS->gKappa(NL-1,TwoSLdown,ILdown,N1,2,TwoS1,NR,TwoSR,IR);
267 int fase =
phase(TwoSLdown+TwoSR+3-TwoJ);
268 double factor = fase*sqrt((TwoSL+1)*(TwoJ+1.0))*
Wigner::wigner6j(TwoS1,TwoJ,1,TwoSL,TwoSLdown,TwoSR);
273 double * BlockQ = Qleft->gStorage(NL-1,TwoSLdown,ILdown,NL,TwoSL,IL);
275 int size = dimLup * dimLdown;
276 dcopy_(&size, BlockQ, &inc, temp, &inc);
278 for (
int l_index=0; l_index<theindex; l_index++){
279 if (denBK->
gIrrep(l_index) == denBK->
gIrrep(theindex+1)){
280 double alpha = Prob->
gMxElement(l_index,theindex+1,theindex+1,theindex+1);
281 double * BlockL = Lleft[theindex-1-l_index]->gStorage(NL-1,TwoSLdown,ILdown,NL,TwoSL,IL);
282 daxpy_(&size, &alpha, BlockL, &inc, temp, &inc);
286 dgemm_(&trans,¬r,&dimLup,&dimR,&dimLdown,&factor,temp,&dimLdown,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
294 void CheMPS2::Heff::addDiagram3C(
const int ikappa,
double * memS,
double * memHeff,
const Sobject * denS, TensorQ ** Qleft, TensorL ** Lright,
double * temp)
const{
296 #ifdef CHEMPS2_MPI_COMPILATION 300 int NL = denS->gNL(ikappa);
301 int TwoSL = denS->gTwoSL(ikappa);
302 int IL = denS->gIL(ikappa);
303 int N1 = denS->gN1(ikappa);
304 int N2 = denS->gN2(ikappa);
305 int TwoJ = denS->gTwoJ(ikappa);
306 int NR = denS->gNR(ikappa);
307 int TwoSR = denS->gTwoSR(ikappa);
308 int IR = denS->gIR(ikappa);
310 int theindex = denS->gIndex();
312 int dimRup = denBK->
gCurrentDim(theindex+2,NR,TwoSR,IR);
313 int dimLup = denBK->
gCurrentDim(theindex, NL,TwoSL,IL);
316 for (
int TwoSLdown=TwoSL-1; TwoSLdown<=TwoSL+1; TwoSLdown+=2){
317 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
318 if ((abs(TwoSLdown-TwoSRdown)<=TwoJ) && (TwoSLdown>=0) && (TwoSRdown>=0)){
320 int fase =
phase(TwoSLdown+TwoSR+TwoJ+1 + ((N1==1)?2:0) + ((N2==1)?2:0) );
321 const double factor = fase * sqrt((TwoSLdown+1)*(TwoSRdown+1.0)) *
Wigner::wigner6j(TwoSL,TwoSR,TwoJ,TwoSRdown,TwoSLdown,1);
323 for (
int l_index=theindex+2; l_index<Prob->
gL(); l_index++){
325 #ifdef CHEMPS2_MPI_COMPILATION 326 if ( MPIchemps2::owner_q( Prob->
gL(), l_index ) == MPIRANK )
331 int memSkappa = denS->gKappa(NL+1, TwoSLdown, ILdown, N1, N2, TwoJ, NR+1, TwoSRdown, IRdown);
333 int dimRdown = denBK->
gCurrentDim(theindex+2, NR+1, TwoSRdown, IRdown);
334 int dimLdown = denBK->
gCurrentDim(theindex, NL+1, TwoSLdown, ILdown);
336 double * Qblock = Qleft[ l_index-theindex ]->gStorage(NL,TwoSL,IL,NL+1,TwoSLdown,ILdown);
337 double * Lblock = Lright[l_index-theindex-2]->gStorage(NR,TwoSR,IR,NR+1,TwoSRdown,IRdown);
342 double alpha = factor;
343 dgemm_(¬ra,¬ra,&dimLup,&dimRdown,&dimLdown,&alpha,Qblock,&dimLup,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,temp,&dimLup);
347 dgemm_(¬ra,&trans,&dimLup,&dimRup,&dimRdown,&alpha,temp,&dimLup,Lblock,&dimRup,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
357 for (
int TwoSLdown=TwoSL-1; TwoSLdown<=TwoSL+1; TwoSLdown+=2){
358 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
359 if ((abs(TwoSLdown-TwoSRdown)<=TwoJ) && (TwoSLdown>=0) && (TwoSRdown>=0)){
361 int fase =
phase(TwoSL+TwoSRdown+TwoJ+1 + ((N1==1)?2:0) + ((N2==1)?2:0) );
362 const double factor = fase * sqrt((TwoSL+1)*(TwoSR+1.0)) *
Wigner::wigner6j(TwoSL,TwoSR,TwoJ,TwoSRdown,TwoSLdown,1);
364 for (
int l_index=theindex+2; l_index<Prob->
gL(); l_index++){
366 #ifdef CHEMPS2_MPI_COMPILATION 367 if ( MPIchemps2::owner_q( Prob->
gL(), l_index ) == MPIRANK )
372 int memSkappa = denS->gKappa(NL-1, TwoSLdown, ILdown, N1, N2, TwoJ, NR-1, TwoSRdown, IRdown);
374 int dimRdown = denBK->
gCurrentDim(theindex+2, NR-1, TwoSRdown, IRdown);
375 int dimLdown = denBK->
gCurrentDim(theindex, NL-1, TwoSLdown, ILdown);
377 double * Qblock = Qleft[ l_index-theindex ]->gStorage(NL-1,TwoSLdown,ILdown,NL,TwoSL,IL);
378 double * Lblock = Lright[l_index-theindex-2]->gStorage(NR-1,TwoSRdown,IRdown,NR,TwoSR,IR);
383 double alpha = factor;
384 dgemm_(&trans,¬ra,&dimLup,&dimRdown,&dimLdown,&alpha,Qblock,&dimLdown,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,temp,&dimLup);
388 dgemm_(¬ra,¬ra,&dimLup,&dimRup,&dimRdown,&alpha,temp,&dimLup,Lblock,&dimRdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
399 void CheMPS2::Heff::addDiagram3Eand3H(
const int ikappa,
double * memS,
double * memHeff,
const Sobject * denS)
const{
401 int theindex = denS->gIndex();
403 if (denBK->
gIrrep(theindex) != denBK->
gIrrep(theindex+1)){
return; }
405 int NL = denS->gNL(ikappa);
406 int TwoSL = denS->gTwoSL(ikappa);
407 int IL = denS->gIL(ikappa);
408 int N1 = denS->gN1(ikappa);
409 int N2 = denS->gN2(ikappa);
410 int TwoJ = denS->gTwoJ(ikappa);
411 int NR = denS->gNR(ikappa);
412 int TwoSR = denS->gTwoSR(ikappa);
413 int IR = denS->gIR(ikappa);
418 if ((N1==2) && (N2==0)){
420 int memSkappa = denS->gKappa(NL,TwoSL,IL,1,1,0,NR,TwoSR,IR);
422 double alpha = sqrt(2.0) * Prob->
gMxElement(theindex,theindex,theindex,theindex+1);
423 daxpy_(&size,&alpha,memS+denS->gKappa2index(memSkappa),&inc,memHeff+denS->gKappa2index(ikappa),&inc);
428 if ((N1==2) && (N2==1)){
430 int memSkappa = denS->gKappa(NL,TwoSL,IL,1,2,1,NR,TwoSR,IR);
432 double alpha = - ( Prob->
gMxElement(theindex,theindex,theindex,theindex+1) + Prob->
gMxElement(theindex,theindex+1,theindex+1,theindex+1) );
433 daxpy_(&size,&alpha,memS+denS->gKappa2index(memSkappa),&inc,memHeff+denS->gKappa2index(ikappa),&inc);
438 if ((N1==1) && (N2==1) && (TwoJ==0)){
440 int memSkappa = denS->gKappa(NL,TwoSL,IL,2,0,0,NR,TwoSR,IR);
442 double alpha = sqrt(2.0) * Prob->
gMxElement(theindex,theindex,theindex,theindex+1);
443 daxpy_(&size,&alpha,memS+denS->gKappa2index(memSkappa),&inc,memHeff+denS->gKappa2index(ikappa),&inc);
446 memSkappa = denS->gKappa(NL,TwoSL,IL,0,2,0,NR,TwoSR,IR);
448 double alpha = sqrt(2.0) * Prob->
gMxElement(theindex,theindex+1,theindex+1,theindex+1);
449 daxpy_(&size,&alpha,memS+denS->gKappa2index(memSkappa),&inc,memHeff+denS->gKappa2index(ikappa),&inc);
454 if ((N1==1) && (N2==2)){
456 int memSkappa = denS->gKappa(NL,TwoSL,IL,2,1,1,NR,TwoSR,IR);
458 double alpha = - ( Prob->
gMxElement(theindex,theindex,theindex,theindex+1) + Prob->
gMxElement(theindex,theindex+1,theindex+1,theindex+1) );
459 daxpy_(&size,&alpha,memS+denS->gKappa2index(memSkappa),&inc,memHeff+denS->gKappa2index(ikappa),&inc);
464 if ((N1==0) && (N2==2)){
466 int memSkappa = denS->gKappa(NL,TwoSL,IL,1,1,0,NR,TwoSR,IR);
468 double alpha = sqrt(2.0) * Prob->
gMxElement(theindex,theindex+1,theindex+1,theindex+1);
469 daxpy_(&size,&alpha,memS+denS->gKappa2index(memSkappa),&inc,memHeff+denS->gKappa2index(ikappa),&inc);
476 void CheMPS2::Heff::addDiagram3Kand3F(
const int ikappa,
double * memS,
double * memHeff,
const Sobject * denS, TensorQ * Qright, TensorL ** Lright,
double * temp)
const{
478 int NL = denS->gNL(ikappa);
479 int TwoSL = denS->gTwoSL(ikappa);
480 int IL = denS->gIL(ikappa);
481 int N1 = denS->gN1(ikappa);
482 int N2 = denS->gN2(ikappa);
483 int TwoJ = denS->gTwoJ(ikappa);
484 int NR = denS->gNR(ikappa);
485 int TwoSR = denS->gTwoSR(ikappa);
486 int IR = denS->gIR(ikappa);
488 int theindex = denS->gIndex();
490 int TwoS2 = (N2==1)?1:0;
492 int dimL = denBK->
gCurrentDim(theindex, NL,TwoSL,IL);
493 int dimRup = denBK->
gCurrentDim(theindex+2,NR,TwoSR,IR);
496 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
497 if ((abs(TwoSL-TwoSRdown)<=TwoS2) && (TwoSRdown>=0)){
498 int dimRdown = denBK->
gCurrentDim(theindex+2, NR-1, TwoSRdown, IRdown);
499 int memSkappa = denS->gKappa(NL,TwoSL,IL,0,N2,TwoS2,NR-1,TwoSRdown,IRdown);
501 int fase =
phase(TwoSL+TwoSR+TwoJ+2*TwoS2);
502 double factor = sqrt((TwoJ+1)*(TwoSR+1.0)) * fase *
Wigner::wigner6j(TwoS2,TwoJ,1,TwoSR,TwoSRdown,TwoSL);
505 double * BlockQ = Qright->gStorage(NR-1,TwoSRdown,IRdown,NR,TwoSR,IR);
506 dgemm_(¬r,¬r,&dimL,&dimRup,&dimRdown,&factor,memS+denS->gKappa2index(memSkappa),&dimL,BlockQ,&dimRdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimL);
513 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
515 int dimRdown = denBK->
gCurrentDim(theindex+2, NR-1, TwoSRdown, IRdown);
518 int TwoJstart = ((TwoSRdown!=TwoSL) || (TwoS2==0)) ? 1 + TwoS2 : 0;
519 for (
int TwoJdown=TwoJstart; TwoJdown<=1+TwoS2; TwoJdown+=2){
520 if (abs(TwoSL-TwoSRdown)<=TwoJdown){
522 int memSkappa = denS->gKappa(NL,TwoSL,IL,1,N2,TwoJdown,NR-1,TwoSRdown,IRdown);
524 int fase =
phase(TwoSL+TwoSR+TwoJdown+1+2*TwoS2);
525 double factor = sqrt((TwoJdown+1)*(TwoSR+1.0)) * fase *
Wigner::wigner6j( TwoJdown, TwoS2, 1, TwoSR, TwoSRdown, TwoSL );
529 double * BlockQ = Qright->gStorage(NR-1,TwoSRdown,IRdown,NR,TwoSR,IR);
531 int size = dimRup * dimRdown;
532 dcopy_(&size,BlockQ,&inc,temp,&inc);
534 for (
int l_index=theindex+2; l_index<Prob->
gL(); l_index++){
536 double alpha = Prob->
gMxElement(theindex,theindex,theindex,l_index);
537 double * BlockL = Lright[l_index-theindex-2]->gStorage(NR-1,TwoSRdown,IRdown,NR,TwoSR,IR);
538 daxpy_(&size, &alpha, BlockL, &inc, temp, &inc);
542 dgemm_(¬r,¬r,&dimL,&dimRup,&dimRdown,&factor,memS+denS->gKappa2index(memSkappa),&dimL,temp,&dimRdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimL);
551 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
553 int dimRdown = denBK->
gCurrentDim(theindex+2, NR+1, TwoSRdown, IRdown);
556 int TwoJstart = ((TwoSRdown!=TwoSL) || (TwoS2==0)) ? 1 + TwoS2 : 0;
557 for (
int TwoJdown=TwoJstart; TwoJdown<=1+TwoS2; TwoJdown+=2){
558 if (abs(TwoSL-TwoSRdown)<=TwoJdown){
560 int memSkappa = denS->gKappa(NL,TwoSL,IL,1,N2,TwoJdown,NR+1,TwoSRdown,IRdown);
562 int fase =
phase(TwoSL+TwoSRdown+TwoJdown+2*TwoS2);
563 double factor = sqrt((TwoJdown+1)*(TwoSRdown+1.0)) * fase *
Wigner::wigner6j(TwoJdown,TwoS2,1,TwoSR,TwoSRdown,TwoSL);
567 double * BlockQ = Qright->gStorage(NR,TwoSR,IR,NR+1,TwoSRdown,IRdown);
568 dgemm_(¬r,&tran,&dimL,&dimRup,&dimRdown,&factor,memS+denS->gKappa2index(memSkappa),&dimL,BlockQ,&dimRup,&beta,memHeff+denS->gKappa2index(ikappa),&dimL);
577 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
578 if ((abs(TwoSL-TwoSRdown)<=TwoS2) && (TwoSRdown>=0)){
579 int dimRdown = denBK->
gCurrentDim(theindex+2, NR+1, TwoSRdown, IRdown);
580 int memSkappa = denS->gKappa(NL,TwoSL,IL,2,N2,TwoS2,NR+1,TwoSRdown,IRdown);
582 int fase =
phase(TwoSL+TwoSRdown+TwoJ+1+2*TwoS2);
583 double factor = sqrt((TwoJ+1)*(TwoSRdown+1.0)) * fase *
Wigner::wigner6j(TwoS2,TwoJ,1,TwoSR,TwoSRdown,TwoSL);
588 double * BlockQ = Qright->gStorage(NR,TwoSR,IR,NR+1,TwoSRdown,IRdown);
590 int size = dimRup * dimRdown;
591 dcopy_(&size,BlockQ,&inc,temp,&inc);
593 for (
int l_index=theindex+2; l_index<Prob->
gL(); l_index++){
595 double alpha = Prob->
gMxElement(theindex,theindex,theindex,l_index);
596 double * BlockL = Lright[l_index-theindex-2]->gStorage(NR,TwoSR,IR,NR+1,TwoSRdown,IRdown);
597 daxpy_(&size, &alpha, BlockL, &inc, temp, &inc);
601 dgemm_(¬r,&tran,&dimL,&dimRup,&dimRdown,&factor,memS+denS->gKappa2index(memSkappa),&dimL,temp,&dimRup,&beta,memHeff+denS->gKappa2index(ikappa),&dimL);
609 void CheMPS2::Heff::addDiagram3Land3G(
const int ikappa,
double * memS,
double * memHeff,
const Sobject * denS, TensorQ * Qright, TensorL ** Lright,
double * temp)
const{
611 int NL = denS->gNL(ikappa);
612 int TwoSL = denS->gTwoSL(ikappa);
613 int IL = denS->gIL(ikappa);
614 int N1 = denS->gN1(ikappa);
615 int N2 = denS->gN2(ikappa);
616 int TwoJ = denS->gTwoJ(ikappa);
617 int NR = denS->gNR(ikappa);
618 int TwoSR = denS->gTwoSR(ikappa);
619 int IR = denS->gIR(ikappa);
621 int theindex = denS->gIndex();
623 int TwoS1 = (N1==1)?1:0;
625 int dimL = denBK->
gCurrentDim(theindex, NL,TwoSL,IL);
626 int dimRup = denBK->
gCurrentDim(theindex+2,NR,TwoSR,IR);
629 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
630 if ((abs(TwoSL-TwoSRdown)<=TwoS1) && (TwoSRdown>=0)){
631 int dimRdown = denBK->
gCurrentDim(theindex+2, NR-1, TwoSRdown, IRdown);
632 int memSkappa = denS->gKappa(NL,TwoSL,IL,N1,0,TwoS1,NR-1,TwoSRdown,IRdown);
634 int fase =
phase(TwoSL+TwoSR+TwoS1+1);
635 double factor = sqrt((TwoJ+1)*(TwoSR+1.0)) * fase *
Wigner::wigner6j(TwoS1,TwoJ,1,TwoSR,TwoSRdown,TwoSL);
638 double * BlockQ = Qright->gStorage(NR-1,TwoSRdown,IRdown,NR,TwoSR,IR);
639 dgemm_(¬r,¬r,&dimL,&dimRup,&dimRdown,&factor,memS+denS->gKappa2index(memSkappa),&dimL,BlockQ,&dimRdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimL);
646 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
648 int dimRdown = denBK->
gCurrentDim(theindex+2, NR-1, TwoSRdown, IRdown);
651 int TwoJstart = ((TwoSRdown!=TwoSL) || (TwoS1==0)) ? 1 + TwoS1 : 0;
652 for (
int TwoJdown=TwoJstart; TwoJdown<=1+TwoS1; TwoJdown+=2){
653 if (abs(TwoSL-TwoSRdown)<=TwoJdown){
655 int memSkappa = denS->gKappa(NL,TwoSL,IL,N1,1,TwoJdown,NR-1,TwoSRdown,IRdown);
657 int fase =
phase(TwoSL+TwoSR+TwoS1+2);
658 double factor = sqrt((TwoJdown+1)*(TwoSR+1.0)) * fase *
Wigner::wigner6j(TwoJdown,TwoS1,1,TwoSR,TwoSRdown,TwoSL);
662 double * BlockQ = Qright->gStorage(NR-1,TwoSRdown,IRdown,NR,TwoSR,IR);
664 int size = dimRup * dimRdown;
665 dcopy_(&size,BlockQ,&inc,temp,&inc);
667 for (
int l_index=theindex+2; l_index<Prob->
gL(); l_index++){
668 if (denBK->
gIrrep(l_index) == denBK->
gIrrep(theindex+1)){
669 double alpha = Prob->
gMxElement(theindex+1,theindex+1,theindex+1,l_index);
670 double * BlockL = Lright[l_index-theindex-2]->gStorage(NR-1,TwoSRdown,IRdown,NR,TwoSR,IR);
671 daxpy_(&size, &alpha, BlockL, &inc, temp, &inc);
675 dgemm_(¬r,¬r,&dimL,&dimRup,&dimRdown,&factor,memS+denS->gKappa2index(memSkappa),&dimL,temp,&dimRdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimL);
684 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
686 int dimRdown = denBK->
gCurrentDim(theindex+2, NR+1, TwoSRdown, IRdown);
689 int TwoJstart = ((TwoSRdown!=TwoSL) || (TwoS1==0)) ? 1 + TwoS1 : 0;
690 for (
int TwoJdown=TwoJstart; TwoJdown<=1+TwoS1; TwoJdown+=2){
691 if (abs(TwoSL-TwoSRdown)<=TwoJdown){
693 int memSkappa = denS->gKappa(NL,TwoSL,IL,N1,1,TwoJdown,NR+1,TwoSRdown,IRdown);
695 int fase =
phase(TwoSL+TwoSRdown+TwoS1+1);
696 double factor = sqrt((TwoJdown+1)*(TwoSRdown+1.0)) * fase *
Wigner::wigner6j(TwoJdown,TwoS1,1,TwoSR,TwoSRdown,TwoSL);
700 double * BlockQ = Qright->gStorage(NR,TwoSR,IR,NR+1,TwoSRdown,IRdown);
701 dgemm_(¬r,&tran,&dimL,&dimRup,&dimRdown,&factor,memS+denS->gKappa2index(memSkappa),&dimL,BlockQ,&dimRup,&beta,memHeff+denS->gKappa2index(ikappa),&dimL);
710 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
711 if ((abs(TwoSL-TwoSRdown)<=TwoS1) && (TwoSRdown>=0)){
712 int dimRdown = denBK->
gCurrentDim(theindex+2, NR+1, TwoSRdown, IRdown);
713 int memSkappa = denS->gKappa(NL,TwoSL,IL,N1,2,TwoS1,NR+1,TwoSRdown,IRdown);
715 int fase =
phase(TwoSL+TwoSRdown+TwoS1+2);
716 double factor = sqrt((TwoJ+1)*(TwoSRdown+1.0)) * fase *
Wigner::wigner6j(TwoS1,TwoJ,1,TwoSR,TwoSRdown,TwoSL);
721 double * BlockQ = Qright->gStorage(NR,TwoSR,IR,NR+1,TwoSRdown,IRdown);
723 int size = dimRup * dimRdown;
724 dcopy_(&size,BlockQ,&inc,temp,&inc);
726 for (
int l_index=theindex+2; l_index<Prob->
gL(); l_index++){
727 if (denBK->
gIrrep(l_index) == denBK->
gIrrep(theindex+1)){
728 double alpha = Prob->
gMxElement(theindex+1,theindex+1,theindex+1,l_index);
729 double * BlockL = Lright[l_index-theindex-2]->gStorage(NR,TwoSR,IR,NR+1,TwoSRdown,IRdown);
730 daxpy_(&size, &alpha, BlockL, &inc, temp, &inc);
734 dgemm_(¬r,&tran,&dimL,&dimRup,&dimRdown,&factor,memS+denS->gKappa2index(memSkappa),&dimL,temp,&dimRup,&beta,memHeff+denS->gKappa2index(ikappa),&dimL);
742 void CheMPS2::Heff::addDiagram3J(
const int ikappa,
double * memS,
double * memHeff,
const Sobject * denS, TensorQ ** Qright, TensorL ** Lleft,
double * temp)
const{
744 #ifdef CHEMPS2_MPI_COMPILATION 748 int NL = denS->gNL(ikappa);
749 int TwoSL = denS->gTwoSL(ikappa);
750 int IL = denS->gIL(ikappa);
751 int N1 = denS->gN1(ikappa);
752 int N2 = denS->gN2(ikappa);
753 int TwoJ = denS->gTwoJ(ikappa);
754 int NR = denS->gNR(ikappa);
755 int TwoSR = denS->gTwoSR(ikappa);
756 int IR = denS->gIR(ikappa);
758 int theindex = denS->gIndex();
760 int dimRup = denBK->
gCurrentDim(theindex+2,NR,TwoSR,IR);
761 int dimLup = denBK->
gCurrentDim(theindex, NL,TwoSL,IL);
764 for (
int TwoSLdown=TwoSL-1; TwoSLdown<=TwoSL+1; TwoSLdown+=2){
765 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
766 if ((abs(TwoSLdown-TwoSRdown)<=TwoJ) && (TwoSLdown>=0) && (TwoSRdown>=0)){
768 int fase =
phase(TwoSLdown+TwoSR+TwoJ+1 + ((N1==1)?2:0) + ((N2==1)?2:0) );
769 const double factor = fase * sqrt((TwoSLdown+1)*(TwoSRdown+1.0)) *
Wigner::wigner6j(TwoSL,TwoSR,TwoJ,TwoSRdown,TwoSLdown,1);
771 for (
int l_index=0; l_index<theindex; l_index++){
773 #ifdef CHEMPS2_MPI_COMPILATION 774 if ( MPIchemps2::owner_q( Prob->
gL(), l_index ) == MPIRANK )
779 int memSkappa = denS->gKappa(NL+1, TwoSLdown, ILdown, N1, N2, TwoJ, NR+1, TwoSRdown, IRdown);
782 int dimRdown = denBK->
gCurrentDim(theindex+2, NR+1, TwoSRdown, IRdown);
783 int dimLdown = denBK->
gCurrentDim(theindex, NL+1, TwoSLdown, ILdown);
785 double * Lblock = Lleft[ theindex-1-l_index]->gStorage(NL,TwoSL,IL,NL+1,TwoSLdown,ILdown);
786 double * Qblock = Qright[theindex+1-l_index]->gStorage(NR,TwoSR,IR,NR+1,TwoSRdown,IRdown);
791 double alpha = factor;
792 dgemm_(¬ra,¬ra,&dimLup,&dimRdown,&dimLdown,&alpha,Lblock,&dimLup,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,temp,&dimLup);
796 dgemm_(¬ra,&trans,&dimLup,&dimRup,&dimRdown,&alpha,temp,&dimLup,Qblock,&dimRup,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
806 for (
int TwoSLdown=TwoSL-1; TwoSLdown<=TwoSL+1; TwoSLdown+=2){
807 for (
int TwoSRdown=TwoSR-1; TwoSRdown<=TwoSR+1; TwoSRdown+=2){
808 if ((abs(TwoSLdown-TwoSRdown)<=TwoJ) && (TwoSLdown>=0) && (TwoSRdown>=0)){
810 int fase =
phase(TwoSL+TwoSRdown+TwoJ+1 + ((N1==1)?2:0) + ((N2==1)?2:0) );
811 const double factor = fase * sqrt((TwoSL+1)*(TwoSR+1.0)) *
Wigner::wigner6j(TwoSL,TwoSR,TwoJ,TwoSRdown,TwoSLdown,1);
813 for (
int l_index=0; l_index<theindex; l_index++){
815 #ifdef CHEMPS2_MPI_COMPILATION 816 if ( MPIchemps2::owner_q( Prob->
gL(), l_index ) == MPIRANK )
821 int memSkappa = denS->gKappa(NL-1, TwoSLdown, ILdown, N1, N2, TwoJ, NR-1, TwoSRdown, IRdown);
823 int dimRdown = denBK->
gCurrentDim(theindex+2, NR-1, TwoSRdown, IRdown);
824 int dimLdown = denBK->
gCurrentDim(theindex, NL-1, TwoSLdown, ILdown);
826 double * Lblock = Lleft[ theindex-1-l_index]->gStorage(NL-1,TwoSLdown,ILdown,NL,TwoSL,IL);
827 double * Qblock = Qright[theindex+1-l_index]->gStorage(NR-1,TwoSRdown,IRdown,NR,TwoSR,IR);
832 double alpha = factor;
833 dgemm_(&trans,¬ra,&dimLup,&dimRdown,&dimLdown,&alpha,Lblock,&dimLdown,memS+denS->gKappa2index(memSkappa),&dimLdown,&beta,temp,&dimLup);
837 dgemm_(¬ra,¬ra,&dimLup,&dimRup,&dimRdown,&alpha,temp,&dimLup,Qblock,&dimRdown,&beta,memHeff+denS->gKappa2index(ikappa),&dimLup);
static double wigner6j(const int two_ja, const int two_jb, const int two_jc, const int two_jd, const int two_je, const int two_jf)
Wigner-6j symbol (gsl api)
int gCurrentDim(const int boundary, const int N, const int TwoS, const int irrep) const
Get the current virtual dimensions.
static int mpi_rank()
Get the rank of this MPI process.
double gMxElement(const int alpha, const int beta, const int gamma, const int delta) const
Get a specific interaction matrix element.
static int directProd(const int Irrep1, const int Irrep2)
Get the direct product of the irreps with numbers Irrep1 and Irrep2: a bitwise XOR for psi4's convent...
int gL() const
Get the number of orbitals.
static int phase(const int TwoTimesPower)
Phase function.
int gIrrep(const int orbital) const
Get an orbital irrep.