48 #pragma omp parallel for schedule(dynamic) 49 for (
int ikappa=0; ikappa<
nKappa; ikappa++){ makenewRight(ikappa, denT); }
52 #pragma omp parallel for schedule(dynamic) 53 for (
int ikappa=0; ikappa<
nKappa; ikappa++){ makenewLeft(ikappa, denT); }
65 const bool doOtherThings = (
index>1) ?
true :
false ;
68 double * workmemLL = (doOtherThings) ?
new double[dimL*dimL] : NULL ;
69 double * workmemLR = (doOtherThings) ?
new double[dimL*dimR] : NULL ;
70 double * workmemRR = (doOtherThings) ?
new double[dimR*dimR] : NULL ;
72 #pragma omp for schedule(dynamic) 73 for (
int ikappa=0; ikappa<
nKappa; ikappa++){
74 makenewRight(ikappa, denT);
77 addTermQLRight(ikappa, denT, Ltensors, Qtensor, workmemRR, workmemLR, workmemLL);
78 addTermARight(ikappa, denT, Atensor, workmemRR, workmemLR);
79 addTermCRight(ikappa, denT, Ctensor, workmemLR);
80 addTermDRight(ikappa, denT, Dtensor, workmemLR);
96 const bool doOtherThings = (
index<Prob->
gL()-1) ?
true :
false ;
99 double * workmemLL = (doOtherThings) ?
new double[dimL*dimL] : NULL ;
100 double * workmemLR = (doOtherThings) ?
new double[dimL*dimR] : NULL ;
101 double * workmemRR = (doOtherThings) ?
new double[dimR*dimR] : NULL ;
103 #pragma omp for schedule(dynamic) 104 for (
int ikappa=0; ikappa<
nKappa; ikappa++){
105 makenewLeft(ikappa, denT);
108 addTermQLLeft(ikappa, denT, Ltensors, Qtensor, workmemLL, workmemLR, workmemRR);
109 addTermALeft(ikappa, denT, Atensor, workmemLR, workmemLL);
110 addTermCLeft(ikappa, denT, Ctensor, workmemLR);
111 addTermDLeft(ikappa, denT, Dtensor, workmemLR);
126 void CheMPS2::TensorX::makenewRight(
const int ikappa,
TensorT * denT){
132 if ((dimL>0) && (fabs(alpha)>0.0)){
138 dgemm_(&trans,¬r,&dimR,&dimR,&dimL,&alpha,BlockT,&dimL,BlockT,&dimL,&beta,
storage+
kappa2index[ikappa],&dimR);
146 void CheMPS2::TensorX::makenewLeft(
const int ikappa,
TensorT * denT){
152 if ((dimR>0) && (fabs(alpha)>0.0)){
158 dgemm_(¬r,&trans,&dimL,&dimL,&dimR,&alpha,BlockT,&dimL,BlockT,&dimL,&beta,
storage+
kappa2index[ikappa],&dimL);
167 void CheMPS2::TensorX::addTermQLRight(
const int ikappa,
TensorT * denT,
TensorL ** Lprev,
TensorQ * Qprev,
double * workmemRR,
double * workmemLR,
double * workmemLL){
170 int dimTot = dimR * dimR;
171 for (
int cnt=0; cnt<dimTot; cnt++){ workmemRR[cnt] = 0.0; }
173 for (
int geval=0; geval<4; geval++){
174 int NLup,TwoSLup,ILup,NLdown,TwoSLdown,ILdown;
212 if ((dimLup>0) && (dimLdown>0)){
215 double * BlockQ = Qprev->
gStorage(NLup, TwoSLup, ILup, NLdown, TwoSLdown, ILdown);
226 int fase = ((((
sector_spin_up[ikappa]+1-TwoSLdown)/2)%2)!=0)?-1:1;
227 factor = fase * sqrt((TwoSLdown + 1.0)/(
sector_spin_up[ikappa] + 1.0));
229 int dimLupdown = dimLup * dimLdown;
232 dcopy_(&dimLupdown,BlockQ,&inc,ptr,&inc);
234 for (
int loca=0; loca<
index-1; loca++){
236 double alpha = Prob->
gMxElement(loca, index-1, index-1, index-1);
237 double * BlockL = Lprev[index-2-loca]->
gStorage(NLup, TwoSLup, ILup, NLdown, TwoSLdown, ILdown);
238 daxpy_(&dimLupdown,&alpha,BlockL,&inc,ptr,&inc);
248 dgemm_(&trans,¬r,&dimR,&dimLdown,&dimLup,&factor,BlockTup,&dimLup,ptr,&dimLup,&beta,workmemLR,&dimR);
253 dgemm_(¬r,¬r,&dimR,&dimR,&dimLdown,&factor,workmemLR,&dimR,BlockTdown,&dimLdown,&beta,workmemRR,&dimR);
258 for (
int irow = 0; irow<dimR; irow++){
259 for (
int icol = irow; icol<dimR; icol++){
260 workmemRR[irow + dimR * icol] += workmemRR[icol + dimR * irow];
261 workmemRR[icol + dimR * irow] = workmemRR[irow + dimR * icol];
270 void CheMPS2::TensorX::addTermQLLeft(
const int ikappa,
TensorT * denT,
TensorL ** Lprev,
TensorQ * Qprev,
double * workmemLL,
double * workmemLR,
double * workmemRR){
273 int dimTot = dimL * dimL;
274 for (
int cnt=0; cnt<dimTot; cnt++){ workmemLL[cnt] = 0.0; }
276 for (
int geval=0; geval<4; geval++){
277 int NRup,TwoSRup,IRup,NRdown,TwoSRdown,IRdown;
315 if ((dimRup>0) && (dimRdown>0)){
318 double * BlockQ = Qprev->
gStorage(NRup, TwoSRup, IRup, NRdown, TwoSRdown, IRdown);
330 factor = fase * sqrt((TwoSRup + 1.0)/(
sector_spin_up[ikappa] + 1.0));
332 int dimRupdown = dimRup * dimRdown;
335 dcopy_(&dimRupdown,BlockQ,&inc,ptr,&inc);
337 for (
int loca=
index+1; loca<Prob->
gL(); loca++){
340 double * BlockL = Lprev[loca-
index-1]->
gStorage(NRup, TwoSRup, IRup, NRdown, TwoSRdown, IRdown);
341 daxpy_(&dimRupdown,&alpha,BlockL,&inc,ptr,&inc);
350 dgemm_(¬r,¬r,&dimL,&dimRdown,&dimRup,&factor,BlockTup,&dimL,ptr,&dimRup,&beta,workmemLR,&dimL);
356 dgemm_(¬r,&trans,&dimL,&dimL,&dimRdown,&factor,workmemLR,&dimL,BlockTdown,&dimL,&beta,workmemLL,&dimL);
361 for (
int irow = 0; irow<dimL; irow++){
362 for (
int icol = irow; icol<dimL; icol++){
363 workmemLL[irow + dimL * icol] += workmemLL[icol + dimL * irow];
364 workmemLL[icol + dimL * irow] = workmemLL[irow + dimL * icol];
373 void CheMPS2::TensorX::addTermARight(
const int ikappa,
TensorT * denT,
TensorOperator * Aprev,
double * workmemRR,
double * workmemLR){
379 if ((dimLup>0) && (dimLdown>0)){
388 double factor = sqrt(2.0);
390 dgemm_(&trans,¬r,&dimR,&dimLdown,&dimLup,&factor,BlockTup,&dimLup,BlockA,&dimLup,&beta,workmemLR,&dimR);
394 dgemm_(¬r,¬r,&dimR,&dimR,&dimLdown,&factor,workmemLR,&dimR,BlockTdown,&dimLdown,&beta,workmemRR,&dimR);
397 for (
int irow = 0; irow<dimR; irow++){
398 for (
int icol = irow; icol<dimR; icol++){
399 workmemRR[irow + dimR * icol] += workmemRR[icol + dimR * irow];
400 workmemRR[icol + dimR * irow] = workmemRR[irow + dimR * icol];
403 int dimTot = dimR * dimR;
412 void CheMPS2::TensorX::addTermALeft(
const int ikappa,
TensorT * denT,
TensorOperator * Aprev,
double * workmemLR,
double * workmemLL){
418 if ((dimRup>0) && (dimRdown>0)){
426 double factor = sqrt(2.0);
428 dgemm_(¬r,¬r,&dimL,&dimRdown,&dimRup,&factor,BlockTup,&dimL,BlockA,&dimRup,&beta,workmemLR,&dimL);
433 dgemm_(¬r,&trans,&dimL,&dimL,&dimRdown,&factor,workmemLR,&dimL,BlockTdown,&dimL,&beta,workmemLL,&dimL);
436 for (
int irow = 0; irow<dimL; irow++){
437 for (
int icol = irow; icol<dimL; icol++){
438 workmemLL[irow + dimL * icol] += workmemLL[icol + dimL * irow];
439 workmemLL[icol + dimL * irow] = workmemLL[irow + dimL * icol];
442 int dimTot = dimL * dimL;
451 void CheMPS2::TensorX::addTermCRight(
const int ikappa,
TensorT * denT,
TensorOperator * denC,
double * workmemLR){
454 for (
int geval=0; geval<3; geval++){
476 double * BlockC = denC->
gStorage(NL,TwoSL,IL,NL,TwoSL,IL);
479 double factor = (geval<2)?sqrt(0.5):sqrt(2.0);
482 dgemm_(&totrans, &totrans, &dimR, &dimL, &dimL, &factor, BlockT, &dimL, BlockC, &dimL, &beta, workmemLR, &dimR);
487 dgemm_(&totrans, &totrans, &dimR, &dimR, &dimL, &factor, workmemLR, &dimR, BlockT, &dimL, &beta,
storage+
kappa2index[ikappa], &dimR);
494 void CheMPS2::TensorX::addTermCLeft(
const int ikappa,
TensorT * denT,
TensorOperator * denC,
double * workmemLR){
497 for (
int geval=0; geval<3; geval++){
519 double * BlockC = denC->
gStorage(NR,TwoSR,IR,NR,TwoSR,IR);
522 double factor = (geval<2)?(sqrt(0.5)*(TwoSR+1.0)/(
sector_spin_up[ikappa]+1.0)):sqrt(2.0);
526 dgemm_(¬r, &trans, &dimL, &dimR, &dimR, &factor, BlockT, &dimL, BlockC, &dimR, &beta, workmemLR, &dimL);
530 dgemm_(¬r, &trans, &dimL, &dimL, &dimR, &factor, workmemLR, &dimL, BlockT, &dimL, &beta,
storage+
kappa2index[ikappa], &dimL);
537 void CheMPS2::TensorX::addTermDRight(
const int ikappa,
TensorT * denT,
TensorOperator * denD,
double * workmemLR){
544 for (
int geval=0; geval<4; geval++){
545 int TwoSLup, TwoSLdown;
568 if ((dimLup>0) && (dimLdown>0)){
570 double * BlockD = denD->
gStorage(NL,TwoSLdown,IL,NL,TwoSLup,IL);
574 int fase = ((((TwoSLdown +
sector_spin_up[ikappa] + 1)/2)%2)!=0)?-1:1;
575 double factor = fase * sqrt(3.0 * (TwoSLup+1))
579 dgemm_(&totrans, &totrans, &dimR, &dimLdown, &dimLup, &factor, BlockTup, &dimLup, BlockD, &dimLdown, &beta, workmemLR, &dimR);
584 dgemm_(&totrans, &totrans, &dimR, &dimR, &dimLdown, &factor, workmemLR, &dimR, BlockTdown, &dimLdown, &beta,
storage+
kappa2index[ikappa], &dimR);
591 void CheMPS2::TensorX::addTermDLeft(
const int ikappa,
TensorT * denT,
TensorOperator * denD,
double * workmemLR){
598 for (
int geval=0; geval<4; geval++){
599 int TwoSRup, TwoSRdown;
622 if ((dimRup>0) && (dimRdown>0)){
624 double * BlockD = denD->
gStorage(NR,TwoSRdown,IR,NR,TwoSRup,IR);
628 int fase = ((((
sector_spin_up[ikappa] + TwoSRdown + 3)/2)%2)!=0)?-1:1;
629 double factor = fase*sqrt(3.0 *(TwoSRup+1))*((TwoSRdown + 1.0)/(
sector_spin_up[ikappa]+1.0))
634 dgemm_(¬r, &trans, &dimL, &dimRdown, &dimRup, &factor, BlockTup, &dimL, BlockD, &dimRdown, &beta, workmemLR, &dimL);
638 dgemm_(¬r, &trans, &dimL, &dimL, &dimRdown, &factor, workmemLR, &dimL, BlockTdown, &dimL, &beta,
storage+
kappa2index[ikappa], &dimL);
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 index
Index of the Tensor object. For TensorT: a site index; for other tensors: a boundary index...
void update(TensorT *denT, TensorL **Ltensors, TensorX *Xtensor, TensorQ *Qtensor, TensorOperator *Atensor, TensorOperator *Ctensor, TensorOperator *Dtensor)
Clear and add the relevant terms to the TensorX.
int * sector_nelec_up
The up particle number sector.
int gCurrentDim(const int boundary, const int N, const int TwoS, const int irrep) const
Get the current virtual dimensions.
double * gStorage()
Get the pointer to the storage.
TensorX(const int boundary_index, const bool moving_right, const SyBookkeeper *denBK, const Problem *Prob)
Constructor.
double gMxElement(const int alpha, const int beta, const int gamma, const int delta) const
Get a specific interaction matrix element.
bool moving_right
Whether or not moving right.
int * sector_spin_up
The up spin symmetry sector.
double * gStorage()
Get the pointer to the storage.
void update_moving_left(const int ikappa, TensorOperator *previous, TensorT *mps_tensor_up, TensorT *mps_tensor_down, double *workmem)
Update moving left.
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.
int * sector_irrep_up
The up spin symmetry sector.
const SyBookkeeper * bk_up
The bookkeeper of the upper MPS.
int * kappa2index
kappa2index[kappa] indicates the start of tensor block kappa in storage. kappa2index[nKappa] gives th...
int gMaxDimAtBound(const int boundary) const
Get the maximum virtual dimension at a certain boundary.
int nKappa
Number of Tensor blocks.
virtual ~TensorX()
Destructor.
int gIrrep(const int orbital) const
Get an orbital irrep.
double * storage
The actual variables. Tensor block kappa begins at storage+kappa2index[kappa] and ends at storage+kap...
void update_moving_right(const int ikappa, TensorOperator *previous, TensorT *mps_tensor_up, TensorT *mps_tensor_down, double *workmem)
Update moving right.