25 #include "SyBookkeeper.h" 33 this->num_irreps = temp.getNumberOfIrreps();
42 CopyDim( FCIdim, CURdim );
45 ScaleCURdim( D, 1,
gL() - 1 );
53 this->Prob = tocopy.
gProb();
55 this->num_irreps = temp.getNumberOfIrreps();
64 for (
int boundary = 0; boundary <=
gL(); boundary++ ){
65 for (
int N =
gNmin( boundary ); N <=
gNmax( boundary ); N++ ){
66 for (
int TwoS =
gTwoSmin( boundary, N ); TwoS <=
gTwoSmax( boundary, N ); TwoS += 2 ){
67 for (
int irrep = 0; irrep < num_irreps; irrep++ ){
68 CURdim[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ][ irrep ] = tocopy.
gCurrentDim( boundary, N, TwoS, irrep );
76 void CheMPS2::SyBookkeeper::allocate_arrays(){
79 Nmin =
new int[
gL() + 1 ];
80 Nmax =
new int[
gL() + 1 ];
81 TwoSmin =
new int*[
gL() + 1 ];
82 TwoSmax =
new int*[
gL() + 1 ];
83 for (
int boundary = 0; boundary <=
gL(); boundary++ ){
84 Nmin[ boundary ] = std::max( std::max( 0,
gN() + 2 * ( boundary -
gL() ) ), boundary -
gL() + (
gN() +
gTwoS() ) / 2 );
85 Nmax[ boundary ] = std::min( std::min( 2 * boundary,
gN() ), boundary + (
gN() -
gTwoS() ) / 2 );
86 TwoSmin[ boundary ] =
new int[ Nmax[ boundary ] - Nmin[ boundary ] + 1 ];
87 TwoSmax[ boundary ] =
new int[ Nmax[ boundary ] - Nmin[ boundary ] + 1 ];
88 for (
int N = Nmin[ boundary ]; N <= Nmax[ boundary ]; N++ ){
89 const int temporary =
gL() - boundary - abs(
gN() - N -
gL() + boundary );
90 TwoSmin[ boundary ][ N - Nmin[ boundary ] ] = std::max( N % 2,
gTwoS() - temporary );
91 TwoSmax[ boundary ][ N - Nmin[ boundary ] ] = std::min( boundary - abs( boundary - N ),
gTwoS() + temporary );
96 FCIdim =
new int***[
gL() + 1 ];
97 CURdim =
new int***[
gL() + 1 ];
98 for (
int boundary = 0; boundary <=
gL(); boundary++ ){
99 FCIdim[ boundary ] =
new int**[
gNmax( boundary ) -
gNmin( boundary ) + 1 ];
100 CURdim[ boundary ] =
new int**[
gNmax( boundary ) -
gNmin( boundary ) + 1 ];
101 for (
int N =
gNmin( boundary ); N <=
gNmax( boundary ); N++ ){
102 FCIdim[ boundary ][ N -
gNmin( boundary ) ] =
new int*[ (
gTwoSmax( boundary, N ) -
gTwoSmin( boundary, N ) ) / 2 + 1 ];
103 CURdim[ boundary ][ N -
gNmin( boundary ) ] =
new int*[ (
gTwoSmax( boundary, N ) -
gTwoSmin( boundary, N ) ) / 2 + 1 ];
104 for (
int TwoS =
gTwoSmin( boundary, N ); TwoS <=
gTwoSmax( boundary, N ); TwoS += 2 ){
105 FCIdim[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ] =
new int[ num_irreps ];
106 CURdim[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ] =
new int[ num_irreps ];
115 for (
int boundary = 0; boundary <=
gL(); boundary++ ){
116 for (
int N =
gNmin( boundary ); N <=
gNmax( boundary ); N++ ){
117 for (
int TwoS =
gTwoSmin( boundary, N ); TwoS <=
gTwoSmax( boundary, N ); TwoS += 2 ){
118 delete [] FCIdim[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ];
119 delete [] CURdim[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ];
121 delete [] FCIdim[ boundary ][ N -
gNmin( boundary ) ];
122 delete [] CURdim[ boundary ][ N -
gNmin( boundary ) ];
124 delete [] FCIdim[ boundary ];
125 delete [] CURdim[ boundary ];
130 for (
int boundary = 0; boundary <=
gL(); boundary++ ){
131 delete [] TwoSmin[ boundary ];
132 delete [] TwoSmax[ boundary ];
163 int CheMPS2::SyBookkeeper::gFCIdim(
const int boundary,
const int N,
const int TwoS,
const int irrep )
const{
return gDimPrivate( FCIdim, boundary, N, TwoS, irrep ); }
169 if (
gFCIdim( boundary, N, TwoS, irrep ) != 0 ){
170 CURdim[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ][ irrep ] = value;
175 void CheMPS2::SyBookkeeper::fillFCIdim(){
178 for (
int irrep = 0; irrep < num_irreps; irrep++ ){ FCIdim[ 0 ][ 0 ][ 0 ][ irrep ] = 0; }
179 FCIdim[ 0 ][ 0 ][ 0 ][ 0 ] = 1;
182 fill_fci_dim_right( FCIdim, 1,
gL() );
185 const int rhs = FCIdim[
gL() ][ 0 ][ 0 ][
gIrrep() ];
188 for (
int irrep = 0; irrep < num_irreps; irrep++ ){ FCIdim[
gL() ][ 0 ][ 0 ][ irrep ] = 0; }
189 FCIdim[
gL() ][ 0 ][ 0 ][
gIrrep() ] = std::min( 1, rhs );
192 fill_fci_dim_left( FCIdim, 0,
gL() - 1 );
196 void CheMPS2::SyBookkeeper::fill_fci_dim_right(
int **** storage,
const int start,
const int stop ){
198 for (
int boundary = start; boundary <= stop; boundary++ ){
199 for (
int N =
gNmin( boundary ); N <=
gNmax( boundary ); N++ ){
200 for (
int TwoS =
gTwoSmin( boundary, N ); TwoS <=
gTwoSmax( boundary, N ); TwoS += 2 ){
201 for (
int irrep = 0; irrep < num_irreps; irrep++ ){
202 const int value = std::min( CheMPS2::SYBK_dimensionCutoff,
203 gDimPrivate( storage, boundary - 1, N, TwoS , irrep )
204 + gDimPrivate( storage, boundary - 1, N - 2, TwoS , irrep )
207 storage[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ][ irrep ] = value;
215 void CheMPS2::SyBookkeeper::fill_fci_dim_left(
int **** storage,
const int start,
const int stop ){
217 for (
int boundary = stop; boundary >= start; boundary-- ){
218 for (
int N =
gNmin( boundary ); N <=
gNmax( boundary ); N++ ){
219 for (
int TwoS =
gTwoSmin( boundary, N ); TwoS <=
gTwoSmax( boundary, N ); TwoS += 2 ){
220 for (
int irrep = 0; irrep < num_irreps; irrep++ ){
221 const int value = std::min( gDimPrivate( storage, boundary, N, TwoS, irrep ),
222 std::min( CheMPS2::SYBK_dimensionCutoff,
223 gDimPrivate( storage, boundary + 1, N, TwoS , irrep )
224 + gDimPrivate( storage, boundary + 1, N + 2, TwoS , irrep )
227 storage[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ][ irrep ] = value;
235 void CheMPS2::SyBookkeeper::CopyDim(
int **** origin,
int **** target ){
237 for (
int boundary = 0; boundary <=
gL(); boundary++ ){
238 for (
int N =
gNmin( boundary ); N <=
gNmax( boundary ); N++ ){
239 for (
int TwoS =
gTwoSmin( boundary, N ); TwoS <=
gTwoSmax( boundary, N ); TwoS += 2 ){
240 for (
int irrep = 0; irrep < num_irreps; irrep++ ){
241 target[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ][ irrep ]
242 = origin[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ][ irrep ];
250 void CheMPS2::SyBookkeeper::ScaleCURdim(
const int virtual_dim,
const int start,
const int stop ){
252 for (
int boundary = start; boundary <= stop; boundary++ ){
256 if ( totaldim > virtual_dim ){
257 double factor = ( 1.0 * virtual_dim ) / totaldim;
258 for (
int N =
gNmin( boundary ); N <=
gNmax( boundary ); N++ ){
259 for (
int TwoS =
gTwoSmin( boundary, N ); TwoS <=
gTwoSmax( boundary, N ); TwoS += 2 ){
260 for (
int irrep = 0; irrep < num_irreps; irrep++ ){
261 const int value = ( int )( ceil( factor *
gCurrentDim( boundary, N, TwoS, irrep ) ) + 0.1 );
262 SetDim( boundary, N, TwoS, irrep, value );
271 int CheMPS2::SyBookkeeper::gDimPrivate(
int **** storage,
const int boundary,
const int N,
const int TwoS,
const int irrep )
const{
273 if (( boundary < 0 ) || ( boundary >
gL() )){
return 0; }
274 if (( N >
gNmax( boundary ) ) || ( N <
gNmin( boundary ) )){
return 0; }
275 if (( TwoS % 2 ) != (
gTwoSmin( boundary, N ) % 2 )){
return 0; }
276 if (( TwoS <
gTwoSmin( boundary, N ) ) || ( TwoS >
gTwoSmax( boundary, N ) )){
return 0; }
277 if (( irrep < 0 ) || ( irrep >= num_irreps )){
return 0; }
278 return storage[ boundary ][ N -
gNmin( boundary ) ][ ( TwoS -
gTwoSmin( boundary, N ) ) / 2 ][ irrep ];
285 for (
int N =
gNmin( boundary ); N <=
gNmax( boundary ); N++ ){
286 for (
int TwoS =
gTwoSmin( boundary, N ); TwoS <=
gTwoSmax( boundary, N ); TwoS += 2 ){
287 for (
int irrep = 0; irrep < num_irreps; irrep++ ){
288 const int dim =
gCurrentDim( boundary, N, TwoS, irrep );
289 if ( dim > max_dim ){ max_dim = dim; }
300 for (
int N =
gNmin( boundary ); N <=
gNmax( boundary ); N++ ){
301 for (
int TwoS =
gTwoSmin( boundary, N ); TwoS <=
gTwoSmax( boundary, N ); TwoS += 2 ){
302 for (
int irrep = 0; irrep < num_irreps; irrep++ ){
303 tot_dim +=
gCurrentDim( boundary, N, TwoS, irrep );
313 fill_fci_dim_right( CURdim, start, stop );
314 fill_fci_dim_left( CURdim, start, stop );
315 ScaleCURdim( virtual_dim, start, stop );
int gNmin(const int boundary) const
Get the min. possible particle number for a certain boundary.
int gTotDimAtBound(const int boundary) const
Get the total reduced virtual dimension at a certain boundary.
SyBookkeeper(const Problem *Prob, const int D)
Constructor.
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.
void restart(const int start, const int stop, const int virtual_dim)
Restart by setting the virtual dimensions from boundary start to boundary stop to FCI virtual dimensi...
int gTwoS() const
Get twice the targeted spin.
virtual ~SyBookkeeper()
Destructor.
const Problem * gProb() const
Get the problem.
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 gN() const
Get the targeted particle number.
int gTwoS() const
Get twice the targeted spin.
int gIrrep() const
Get the targeted irrep.
int gIrrep(const int nOrb) const
Get an orbital irrep.
bool IsPossible() const
Get whether the desired symmetry sector is possible.
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 getNumberOfIrreps() const
Get the total number of irreps.
int gL() const
Get the number of orbitals.
int gMaxDimAtBound(const int boundary) const
Get the maximum virtual dimension at a certain boundary.
int gNmax(const int boundary) const
Get the max. possible particle number for a certain boundary.
void SetDim(const int boundary, const int N, const int TwoS, const int irrep, const int value)
Get the current virtual dimensions.
int gN() const
Get the targeted particle number.
int gSy() const
Get the point group symmetry.