27 #include "SyBookkeeper.h" 29 #include "MPIchemps2.h" 40 Ilocal1 = denBK->
gIrrep( index );
41 Ilocal2 = denBK->
gIrrep( index + 1 );
45 for (
int NL = denBK->
gNmin( index ); NL <= denBK->
gNmax( index ); NL++ ){
46 for (
int TwoSL = denBK->
gTwoSmin( index, NL ); TwoSL <= denBK->
gTwoSmax( index, NL ); TwoSL += 2 ){
48 const int dimL = denBK->
gCurrentDim( index, NL, TwoSL, IL );
50 for (
int N1 = 0; N1 <= 2; N1++ ){
51 for (
int N2 = 0; N2 <= 2; N2++ ){
52 const int NR = NL + N1 + N2;
55 const int TwoJmin = ( N1 + N2 ) % 2;
56 const int TwoJmax = ((( N1 == 1 ) && ( N2 == 1 )) ? 2 : TwoJmin );
57 for (
int TwoJ = TwoJmin; TwoJ <= TwoJmax; TwoJ += 2 ){
58 for (
int TwoSR = TwoSL - TwoJ; TwoSR <= TwoSL + TwoJ; TwoSR += 2 ){
60 const int dimR = denBK->
gCurrentDim( index + 2, NR, TwoSR, IR );
74 sectorNL =
new int[ nKappa ];
75 sectorTwoSL =
new int[ nKappa ];
76 sectorIL =
new int[ nKappa ];
77 sectorN1 =
new int[ nKappa ];
78 sectorN2 =
new int[ nKappa ];
79 sectorTwoJ =
new int[ nKappa ];
80 sectorNR =
new int[ nKappa ];
81 sectorTwoSR =
new int[ nKappa ];
82 sectorIR =
new int[ nKappa ];
83 kappa2index =
new int[ nKappa + 1 ];
88 for (
int NL = denBK->
gNmin( index ); NL <= denBK->
gNmax( index ); NL++ ){
89 for (
int TwoSL = denBK->
gTwoSmin( index, NL ); TwoSL <= denBK->
gTwoSmax( index, NL ); TwoSL += 2 ){
91 const int dimL = denBK->
gCurrentDim( index, NL, TwoSL, IL );
93 for (
int N1 = 0; N1 <= 2; N1++ ){
94 for (
int N2 = 0; N2 <= 2; N2++ ){
95 const int NR = NL + N1 + N2;
98 const int TwoJmin = ( N1 + N2 ) % 2;
99 const int TwoJmax = ((( N1 == 1 ) && ( N2 == 1 )) ? 2 : TwoJmin );
100 for (
int TwoJ = TwoJmin; TwoJ <= TwoJmax; TwoJ += 2 ){
101 for (
int TwoSR = TwoSL - TwoJ; TwoSR <= TwoSL + TwoJ; TwoSR += 2 ){
103 const int dimR = denBK->
gCurrentDim( index + 2, NR, TwoSR, IR );
105 sectorNL [ nKappa ] = NL;
106 sectorTwoSL[ nKappa ] = TwoSL;
107 sectorIL [ nKappa ] = IL;
108 sectorN1 [ nKappa ] = N1;
109 sectorN2 [ nKappa ] = N2;
110 sectorTwoJ [ nKappa ] = TwoJ;
111 sectorNR [ nKappa ] = NR;
112 sectorTwoSR[ nKappa ] = TwoSR;
113 sectorIR [ nKappa ] = IR;
115 kappa2index[ nKappa ] = kappa2index[ nKappa - 1 ] + dimL * dimR;
127 storage =
new double[ kappa2index[ nKappa ] ];
129 reorder =
new int[ nKappa ];
130 for (
int cnt = 0; cnt < nKappa; cnt++ ){ reorder[ cnt ] = cnt; }
132 while ( sorted ==
false ){
134 for (
int cnt = 0; cnt < nKappa - 1; cnt++ ){
135 const int index1 = reorder[ cnt ];
136 const int index2 = reorder[ cnt + 1 ];
137 const int size1 = kappa2index[ index1 + 1 ] - kappa2index[ index1 ];
138 const int size2 = kappa2index[ index2 + 1 ] - kappa2index[ index2 ];
139 if ( size1 < size2 ){
141 reorder[ cnt ] = index2;
142 reorder[ cnt + 1 ] = index1;
152 delete [] sectorTwoSL;
156 delete [] sectorTwoJ;
158 delete [] sectorTwoSR;
160 delete [] kappa2index;
172 int CheMPS2::Sobject::gKappa(
const int NL,
const int TwoSL,
const int IL,
const int N1,
const int N2,
const int TwoJ,
const int NR,
const int TwoSR,
const int IR )
const{
174 for (
int ikappa = 0; ikappa < nKappa; ikappa++ ){
175 if (( sectorNL [ ikappa ] == NL ) &&
176 ( sectorTwoSL[ ikappa ] == TwoSL ) &&
177 ( sectorIL [ ikappa ] == IL ) &&
178 ( sectorN1 [ ikappa ] == N1 ) &&
179 ( sectorN2 [ ikappa ] == N2 ) &&
180 ( sectorTwoJ [ ikappa ] == TwoJ ) &&
181 ( sectorNR [ ikappa ] == NR ) &&
182 ( sectorTwoSR[ ikappa ] == TwoSR ) &&
183 ( sectorIR [ ikappa ] == IR )){
return ikappa; }
192 double *
CheMPS2::Sobject::gStorage(
const int NL,
const int TwoSL,
const int IL,
const int N1,
const int N2,
const int TwoJ,
const int NR,
const int TwoSR,
const int IR ){
194 const int kappa =
gKappa( NL, TwoSL, IL, N1, N2, TwoJ, NR, TwoSR, IR );
195 if ( kappa == -1 ){
return NULL; }
196 return storage + kappa2index[ kappa ];
214 #pragma omp parallel for schedule(dynamic) 215 for (
int ikappa = 0; ikappa < nKappa; ikappa++ ){
217 const int NL = sectorNL [ ikappa ];
218 const int TwoSL = sectorTwoSL[ ikappa ];
219 const int IL = sectorIL [ ikappa ];
221 const int NR = sectorNR [ ikappa ];
222 const int TwoSR = sectorTwoSR[ ikappa ];
223 const int IR = sectorIR [ ikappa ];
225 const int TwoJ = sectorTwoJ [ ikappa ];
226 const int N1 = sectorN1 [ ikappa ];
227 const int N2 = sectorN2 [ ikappa ];
228 const int TwoS1 = (( N1 == 1 ) ? 1 : 0 );
229 const int TwoS2 = (( N2 == 1 ) ? 1 : 0 );
233 int dimL = denBK->
gCurrentDim( index, NL, TwoSL, IL );
234 int dimR = denBK->
gCurrentDim( index + 2, NR, TwoSR, IR );
235 double * block_s = storage + kappa2index[ ikappa ];
236 for (
int cnt = 0; cnt < dimL * dimR; cnt++ ){ block_s[ cnt ] = 0.0; }
239 const int NM = NL + N1;
241 const int TwoJMlower = max( abs( TwoSL - TwoS1 ), abs( TwoSR - TwoS2 ) );
242 const int TwoJMupper = min( ( TwoSL + TwoS1 ), ( TwoSR + TwoS2 ) );
243 for (
int TwoJM = TwoJMlower; TwoJM <= TwoJMupper; TwoJM += 2 ){
244 int dimM = denBK->
gCurrentDim( index + 1, NM, TwoJM, IM );
246 double * block_left = Tleft ->
gStorage( NL, TwoSL, IL, NM, TwoJM, IM );
247 double * block_right = Tright->
gStorage( NM, TwoJM, IM, NR, TwoSR, IR );
248 double prefactor = fase
249 * sqrt( 1.0 * ( TwoJ + 1 ) * ( TwoJM + 1 ) )
253 dgemm_( ¬rans, ¬rans, &dimL, &dimR, &dimM, &prefactor, block_left, &dimL, block_right, &dimM, &add, block_s, &dimL );
262 #ifdef CHEMPS2_MPI_COMPILATION 267 int nCenterSectors = 0;
268 for (
int NM = denBK->
gNmin( index + 1 ); NM <= denBK->
gNmax( index + 1 ); NM++ ){
269 for (
int TwoSM = denBK->
gTwoSmin( index + 1, NM ); TwoSM <= denBK->
gTwoSmax( index + 1, NM ); TwoSM += 2 ){
271 const int dimM = denBK->
gFCIdim( index + 1, NM, TwoSM, IM );
280 int * SplitSectNM =
new int[ nCenterSectors ];
281 int * SplitSectTwoJM =
new int[ nCenterSectors ];
282 int * SplitSectIM =
new int[ nCenterSectors ];
284 for (
int NM = denBK->
gNmin( index + 1 ); NM <= denBK->
gNmax( index + 1 ); NM++ ){
285 for (
int TwoSM = denBK->
gTwoSmin( index + 1, NM ); TwoSM <= denBK->
gTwoSmax( index + 1, NM ); TwoSM += 2 ){
287 const int dimM = denBK->
gFCIdim( index + 1, NM, TwoSM, IM );
289 SplitSectNM [ nCenterSectors ] = NM;
290 SplitSectTwoJM[ nCenterSectors ] = TwoSM;
291 SplitSectIM [ nCenterSectors ] = IM;
299 double ** Lambdas = NULL;
301 double ** VTs = NULL;
302 int * CenterDims = NULL;
303 int * DimLtotal = NULL;
304 int * DimRtotal = NULL;
306 #ifdef CHEMPS2_MPI_COMPILATION 310 Lambdas =
new double*[ nCenterSectors ];
311 Us =
new double*[ nCenterSectors ];
312 VTs =
new double*[ nCenterSectors ];
313 CenterDims =
new int[ nCenterSectors ];
314 DimLtotal =
new int[ nCenterSectors ];
315 DimRtotal =
new int[ nCenterSectors ];
318 #pragma omp parallel for schedule(dynamic) 319 for (
int iCenter = 0; iCenter < nCenterSectors; iCenter++ ){
322 DimLtotal[ iCenter ] = 0;
323 for (
int NL = SplitSectNM[ iCenter ] - 2; NL <= SplitSectNM[ iCenter ]; NL++ ){
324 const int TwoS1 = (( NL + 1 == SplitSectNM[ iCenter ] ) ? 1 : 0 );
325 for (
int TwoSL = SplitSectTwoJM[ iCenter ] - TwoS1; TwoSL <= SplitSectTwoJM[ iCenter ] + TwoS1; TwoSL += 2 ){
327 const int IL = (( TwoS1 == 1 ) ?
Irreps::directProd( Ilocal1, SplitSectIM[ iCenter ] ) : SplitSectIM[ iCenter ] );
328 const int dimL = denBK->
gCurrentDim( index, NL, TwoSL, IL );
330 DimLtotal[ iCenter ] += dimL;
335 DimRtotal[ iCenter ] = 0;
336 for (
int NR = SplitSectNM[ iCenter ]; NR <= SplitSectNM[ iCenter ] + 2; NR++ ){
337 const int TwoS2 = (( NR == SplitSectNM[ iCenter ] + 1 ) ? 1 : 0 );
338 for (
int TwoSR = SplitSectTwoJM[ iCenter ] - TwoS2; TwoSR <= SplitSectTwoJM[ iCenter ] + TwoS2; TwoSR += 2 ){
340 const int IR = (( TwoS2 == 1 ) ?
Irreps::directProd( Ilocal2, SplitSectIM[ iCenter ] ) : SplitSectIM[ iCenter ] );
341 const int dimR = denBK->
gCurrentDim( index + 2, NR, TwoSR, IR );
343 DimRtotal[ iCenter ] += dimR;
348 CenterDims[ iCenter ] = min( DimLtotal[ iCenter ], DimRtotal[ iCenter ] );
351 if ( CenterDims[ iCenter ] > 0 ){
354 Lambdas[ iCenter ] =
new double[ CenterDims[ iCenter ] ];
355 Us[ iCenter ] =
new double[ CenterDims[ iCenter ] * DimLtotal[ iCenter ] ];
356 VTs[ iCenter ] =
new double[ CenterDims[ iCenter ] * DimRtotal[ iCenter ] ];
358 const int memsize = DimLtotal[ iCenter ] * DimRtotal[ iCenter ];
359 double * mem =
new double[ memsize ];
360 for (
int cnt = 0; cnt < memsize; cnt++ ){ mem[ cnt ] = 0.0; }
363 for (
int NL = SplitSectNM[ iCenter ] - 2; NL <= SplitSectNM[ iCenter ]; NL++ ){
364 const int TwoS1 = (( NL + 1 == SplitSectNM[ iCenter ] ) ? 1 : 0 );
365 for (
int TwoSL = SplitSectTwoJM[ iCenter ] - TwoS1; TwoSL <= SplitSectTwoJM[ iCenter ] + TwoS1; TwoSL += 2 ){
367 const int IL = (( TwoS1 == 1 ) ?
Irreps::directProd( Ilocal1, SplitSectIM[ iCenter ] ) : SplitSectIM[ iCenter ] );
368 const int dimL = denBK->
gCurrentDim( index, NL, TwoSL, IL );
371 for (
int NR = SplitSectNM[ iCenter ]; NR <= SplitSectNM[ iCenter ] + 2; NR++ ){
372 const int TwoS2 = (( NR == SplitSectNM[ iCenter ] + 1 ) ? 1 : 0 );
373 for (
int TwoSR = SplitSectTwoJM[ iCenter ] - TwoS2; TwoSR <= SplitSectTwoJM[ iCenter ] + TwoS2; TwoSR += 2 ){
375 const int IR = (( TwoS2 == 1 ) ?
Irreps::directProd( Ilocal2, SplitSectIM[ iCenter ] ) : SplitSectIM[ iCenter ] );
376 const int dimR = denBK->
gCurrentDim( index + 2, NR, TwoSR, IR );
380 const int TwoJmin = max( abs( TwoSR - TwoSL ), abs( TwoS2 - TwoS1 ) );
381 const int TwoJmax = min( TwoS1 + TwoS2, TwoSL + TwoSR );
382 for (
int TwoJ = TwoJmin; TwoJ <= TwoJmax; TwoJ += 2 ){
384 const double prefactor = fase
385 * sqrt( 1.0 * ( TwoJ + 1 ) * ( TwoSR + 1 ) )
386 *
Wigner::wigner6j( TwoSL, TwoSR, TwoJ, TwoS2, TwoS1, SplitSectTwoJM[ iCenter ] );
389 double * Block =
gStorage( NL, TwoSL, IL, SplitSectNM[ iCenter ] - NL, NR - SplitSectNM[ iCenter ], TwoJ, NR, TwoSR, IR );
390 for (
int l = 0; l < dimL; l++ ){
391 for (
int r = 0; r < dimR; r++ ){
392 mem[ dimLtotal2 + l + DimLtotal[ iCenter ] * ( dimRtotal2 + r ) ] += prefactor * Block[ l + dimL * r ];
409 int lwork = 3 * CenterDims[ iCenter ] + max( max( DimLtotal[ iCenter ], DimRtotal[ iCenter ] ), 4 * CenterDims[ iCenter ] * ( CenterDims[ iCenter ] + 1 ) );
410 double * work =
new double[ lwork ];
411 int * iwork =
new int[ 8 * CenterDims[ iCenter ] ];
416 dgesdd_( &jobz, DimLtotal + iCenter, DimRtotal + iCenter, mem, DimLtotal + iCenter,
417 Lambdas[ iCenter ], Us[ iCenter ], DimLtotal + iCenter, VTs[ iCenter ], CenterDims + iCenter, work, &lwork, iwork, &info );
425 #ifdef CHEMPS2_MPI_COMPILATION 429 double discardedWeight = 0.0;
430 int updateSectors = 0;
431 int * NewDims = NULL;
434 #ifdef CHEMPS2_MPI_COMPILATION 435 if (( change ) && ( am_i_master )){
440 NewDims =
new int[ nCenterSectors ];
443 for (
int iCenter = 0; iCenter < nCenterSectors; iCenter++ ){
444 NewDims[ iCenter ] = CenterDims[ iCenter ];
445 totalDimSVD += NewDims[ iCenter ];
449 if ( totalDimSVD > virtualdimensionD ){
451 double * values =
new double[ totalDimSVD ];
454 for (
int iCenter = 0; iCenter < nCenterSectors; iCenter++ ){
455 if ( NewDims[ iCenter ] > 0 ){
456 dcopy_( NewDims + iCenter, Lambdas[ iCenter ], &inc, values + totalDimSVD, &inc );
457 totalDimSVD += NewDims[ iCenter ];
464 dlasrt_( &ID, &totalDimSVD, values, &info );
467 const double lowerBound = values[ virtualdimensionD ];
468 for (
int iCenter = 0; iCenter < nCenterSectors; iCenter++ ){
469 for (
int cnt = 0; cnt < NewDims[ iCenter ]; cnt++ ){
470 if ( Lambdas[ iCenter ][ cnt ] <= lowerBound ){ NewDims[ iCenter ] = cnt; }
475 double totalSum = 0.0;
476 double discardedSum = 0.0;
477 for (
int iCenter = 0; iCenter < nCenterSectors; iCenter++ ){
478 for (
int iLocal = 0; iLocal < CenterDims[ iCenter ]; iLocal++ ){
479 double temp = ( SplitSectTwoJM[ iCenter ] + 1 ) * Lambdas[ iCenter ][ iLocal ] * Lambdas[ iCenter ][ iLocal ];
481 if ( Lambdas[ iCenter ][ iLocal ] <= lowerBound ){ discardedSum += temp; }
484 discardedWeight = discardedSum / totalSum;
492 for (
int iCenter = 0; iCenter < nCenterSectors; iCenter++ ){
493 const int MPSdim = denBK->
gCurrentDim( index + 1, SplitSectNM[ iCenter ], SplitSectTwoJM[ iCenter ], SplitSectIM[ iCenter ] );
494 if ( NewDims[ iCenter ] != MPSdim ){ updateSectors = 1; }
499 #ifdef CHEMPS2_MPI_COMPILATION 500 MPIchemps2::broadcast_array_int( &updateSectors, 1, MPI_CHEMPS2_MASTER );
501 MPIchemps2::broadcast_array_double( &discardedWeight, 1, MPI_CHEMPS2_MASTER );
504 if ( updateSectors == 1 ){
506 #ifdef CHEMPS2_MPI_COMPILATION 507 if ( NewDims == NULL ){ NewDims =
new int[ nCenterSectors ]; }
508 MPIchemps2::broadcast_array_int( NewDims, nCenterSectors, MPI_CHEMPS2_MASTER );
511 for (
int iCenter = 0; iCenter < nCenterSectors; iCenter++ ){
512 denBK->
SetDim( index + 1, SplitSectNM[ iCenter ], SplitSectTwoJM[ iCenter ], SplitSectIM[ iCenter ], NewDims[ iCenter ] );
519 if ( NewDims != NULL ){
delete [] NewDims; }
521 #ifdef CHEMPS2_MPI_COMPILATION 526 #pragma omp parallel for schedule(dynamic) 527 for (
int iCenter = 0; iCenter < nCenterSectors; iCenter++ ){
528 const int dimM = denBK->
gCurrentDim( index + 1, SplitSectNM[ iCenter ], SplitSectTwoJM[ iCenter ], SplitSectIM[ iCenter ] );
532 for (
int NL = SplitSectNM[ iCenter ] - 2; NL <= SplitSectNM[ iCenter ]; NL++ ){
533 const int TwoS1 = (( NL + 1 == SplitSectNM[ iCenter ] ) ? 1 : 0 );
534 for (
int TwoSL = SplitSectTwoJM[ iCenter ] - TwoS1; TwoSL <= SplitSectTwoJM[ iCenter ] + TwoS1; TwoSL += 2 ){
536 const int IL = (( TwoS1 == 1 ) ?
Irreps::directProd( Ilocal1, SplitSectIM[ iCenter ] ) : SplitSectIM[ iCenter ] );
537 const int dimL = denBK->
gCurrentDim( index, NL, TwoSL, IL );
539 double * TleftBlock = Tleft->
gStorage( NL, TwoSL, IL, SplitSectNM[ iCenter ], SplitSectTwoJM[ iCenter ], SplitSectIM[ iCenter ] );
540 const int dimension_limit_right = min( dimM, CenterDims[ iCenter ] );
541 for (
int r = 0; r < dimension_limit_right; r++ ){
542 const double factor = (( movingright ) ? 1.0 : Lambdas[ iCenter ][ r ] );
543 for (
int l = 0; l < dimL; l++ ){
544 TleftBlock[ l + dimL * r ] = factor * Us[ iCenter ][ dimLtotal2 + l + DimLtotal[ iCenter ] * r ];
547 for (
int r = dimension_limit_right; r < dimM; r++ ){
548 for (
int l = 0; l < dimL; l++ ){
549 TleftBlock[ l + dimL * r ] = 0.0;
560 for (
int NR = SplitSectNM[ iCenter ]; NR <= SplitSectNM[ iCenter ] + 2; NR++ ){
561 const int TwoS2 = (( NR == SplitSectNM[ iCenter ] + 1 ) ? 1 : 0 );
562 for (
int TwoSR = SplitSectTwoJM[ iCenter ] - TwoS2; TwoSR <= SplitSectTwoJM[ iCenter ] + TwoS2; TwoSR += 2 ){
564 const int IR = (( TwoS2 == 1 ) ?
Irreps::directProd( Ilocal2, SplitSectIM[ iCenter ] ) : SplitSectIM[ iCenter ] );
565 const int dimR = denBK->
gCurrentDim( index + 2, NR, TwoSR, IR );
567 double * TrightBlock = Tright->
gStorage( SplitSectNM[ iCenter ], SplitSectTwoJM[ iCenter ], SplitSectIM[ iCenter ], NR, TwoSR, IR );
568 const int dimension_limit_left = min( dimM, CenterDims[ iCenter ] );
569 const double factor_base = sqrt( ( SplitSectTwoJM[ iCenter ] + 1.0 ) / ( TwoSR + 1 ) );
570 for (
int l = 0; l < dimension_limit_left; l++ ){
571 const double factor = factor_base * (( movingright ) ? Lambdas[ iCenter ][ l ] : 1.0 );
572 for (
int r = 0; r < dimR; r++ ){
573 TrightBlock[ l + dimM * r ] = factor * VTs[ iCenter ][ l + CenterDims[ iCenter ] * ( dimRtotal2 + r ) ];
576 for (
int r = 0; r < dimR; r++ ){
577 for (
int l = dimension_limit_left; l < dimM; l++ ){
578 TrightBlock[ l + dimM * r ] = 0.0;
589 #ifdef CHEMPS2_MPI_COMPILATION 591 MPIchemps2::broadcast_tensor( Tleft, MPI_CHEMPS2_MASTER );
592 MPIchemps2::broadcast_tensor( Tright, MPI_CHEMPS2_MASTER );
596 delete [] SplitSectNM;
597 delete [] SplitSectTwoJM;
598 delete [] SplitSectIM;
599 #ifdef CHEMPS2_MPI_COMPILATION 603 for (
int iCenter = 0; iCenter < nCenterSectors; iCenter++ ){
604 if ( CenterDims[ iCenter ] > 0 ){
605 delete [] Us[ iCenter ];
606 delete [] Lambdas[ iCenter ];
607 delete [] VTs[ iCenter ];
613 delete [] CenterDims;
618 return discardedWeight;
624 #pragma omp parallel for schedule(dynamic) 625 for (
int ikappa = 0; ikappa < nKappa; ikappa++ ){
627 int dim = kappa2index[ ikappa + 1 ] - kappa2index[ ikappa ];
628 double alpha = sqrt( sectorTwoSR[ ikappa ] + 1.0 );
630 dscal_( &dim, &alpha, storage + kappa2index[ ikappa ], &inc );
638 #pragma omp parallel for schedule(dynamic) 639 for (
int ikappa = 0; ikappa < nKappa; ikappa++ ){
641 int dim = kappa2index[ ikappa + 1 ] - kappa2index[ ikappa ];
642 double alpha = 1.0 / sqrt( sectorTwoSR[ ikappa ] + 1.0 );
644 dscal_( &dim, &alpha, storage + kappa2index[ ikappa ], &inc );
653 const double RN = ( ( double ) rand() ) / RAND_MAX - 0.5;
654 gStorage()[ cnt ] += RN * NoiseLevel;
int gTwoSL(const int ikappa) const
Get the left spin symmetry of block ikappa.
Sobject(const int index, SyBookkeeper *denBK)
Constructor.
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 gNmin(const int boundary) const
Get the min. possible particle number for a certain boundary.
int gFCIdim(const int boundary, const int N, const int TwoS, const int irrep) const
Get the FCI virtual dimensions ( bound by SYBK_dimensionCutoff )
int gCurrentDim(const int boundary, const int N, const int TwoS, const int irrep) const
Get the current virtual dimensions.
int gKappa2index(const int kappa) const
Get the storage jump corresponding to a certain symmetry block.
double Split(TensorT *Tleft, TensorT *Tright, const int virtualdimensionD, const bool movingright, const bool change)
SVD an S-object into 2 TensorT's.
static int mpi_rank()
Get the rank of this MPI process.
void symm2prog()
Convert the storage from symmetric Hamiltonian convention to diagram convention.
static int phase(const int power_times_two)
Phase function.
int gTwoJ(const int ikappa) const
Get the central spin symmetry of block ikappa.
int gTwoSmin(const int boundary, const int N) const
Get the minimum possible spin value for a certain boundary and particle number.
int gTwoSmax(const int boundary, const int N) const
Get the maximum possible spin value for a certain boundary and particle number.
int gNKappa() const
Get the number of symmetry blocks.
int gIL(const int ikappa) const
Get the left irrep symmetry of block ikappa.
double * gStorage()
Get the pointer to the storage.
double * gStorage()
Get the pointer to the storage.
int gKappa(const int NL, const int TwoSL, const int IL, const int N1, const int N2, const int TwoJ, const int NR, const int TwoSR, const int IR) const
Get the index corresponding to a certain symmetry block.
void Join(TensorT *Tleft, TensorT *Tright)
Join two sites to form a composite S-object.
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...
void prog2symm()
Convert the storage from diagram convention to symmetric Hamiltonian convention.
virtual ~Sobject()
Destructor.
int getNumberOfIrreps() const
Get the total number of irreps.
int gNL(const int ikappa) const
Get the left particle number symmetry of block ikappa.
int gIR(const int ikappa) const
Get the right irrep symmetry of block ikappa.
int gTwoSR(const int ikappa) const
Get the right spin symmetry of block ikappa.
int gIndex() const
Get the location index.
int gReorder(const int ikappa) const
Get the blocks from large to small: blocksize(reorder[i])>=blocksize(reorder[i+1]) ...
int gNmax(const int boundary) const
Get the max. possible particle number for a certain boundary.
int gNR(const int ikappa) const
Get the right particle number symmetry of block ikappa.
void SetDim(const int boundary, const int N, const int TwoS, const int irrep, const int value)
Get the current virtual dimensions.
int gIrrep(const int orbital) const
Get an orbital irrep.
void addNoise(const double NoiseLevel)
Add noise to the current S-object.
int gN1(const int ikappa) const
Get the left local particle number symmetry of block ikappa.
void Reset()
Reset the TensorT (if virtual dimensions are changed)
int gN2(const int ikappa) const
Get the right local particle number symmetry of block ikappa.