29 #define HDF5_STATUS_CHECK(status) { \
31 std::cerr << __FILE__ << ":" << __LINE__ << \
32 ": Problem with writing to file. Status code=" \
33 << status << std::endl; \
47 std::cerr <<
"There will be trouble: make sure the number of particles is even!" << std::endl;
57 std::cout <<
"Swapping Nu and Nd to have positive Sz!" << std::endl;
93 #pragma omp parallel for
94 for(
int i=0;i<
spinbasis->getnumblocks();i++)
99 if(myS != -1 && S != myS)
102 std::cout <<
"Building K=" << K <<
" S=" << S << std::endl;
104 int cur_dim =
spinbasis->getBlock(i).getspacedim();
107 std::unique_ptr<double []> hop(
new double[cur_dim]);
108 std::unique_ptr<int []> interact(
new int[cur_dim*cur_dim]);
110 for(
int a=0;a<cur_dim;a++)
112 auto bra =
spinbasis->getBlock(i).Get(a);
115 for(
int b=a;b<cur_dim;b++)
117 auto ket =
spinbasis->getBlock(i).Get(b);
119 interact[b+a*cur_dim] =
interaction(bra.first, bra.second, ket.first, ket.second);
120 interact[a+b*cur_dim] = interact[b+a*cur_dim];
124 std::cout <<
"Filling hamiltonian" << std::endl;
126 int mydim =
spinbasis->getBlock(i).getdim();
127 std::unique_ptr<matrix> tmp (
new matrix (mydim,mydim));
129 auto &sparse =
spinbasis->getBlock(i).getSparse();
131 #pragma omp parallel for schedule(guided)
132 for(
int a=0;a<mydim;a++)
134 for(
int b=a;b<mydim;b++)
138 for(
int k=0;k<sparse.NumOfElInCol(a);k++)
139 for(
int l=0;l<sparse.NumOfElInCol(b);l++)
141 if(sparse.GetElementRowIndexInCol(a,k) == sparse.GetElementRowIndexInCol(b,l) )
142 (*tmp)(a,b) += sparse.GetElementInCol(a,k) * sparse.GetElementInCol(b,l) * \
143 J * hop[sparse.GetElementRowIndexInCol(a,k)];
145 (*tmp)(a,b) += sparse.GetElementInCol(a,k) * sparse.GetElementInCol(b,l) *
U/
L * \
146 interact[sparse.GetElementRowIndexInCol(a,k) + cur_dim * sparse.GetElementRowIndexInCol(b,l)];
149 (*tmp)(b,a) = (*tmp)(a,b);
165 #pragma omp parallel for
166 for(
int i=0;i<
spinbasis->getnumblocks();i++)
173 std::cout <<
"Building K=" << K <<
" S=" << S << std::endl;
176 int cur_dim =
spinbasis->getBlock(i).getspacedim();
179 std::unique_ptr<double []> hop(
new double[cur_dim]);
180 std::unique_ptr<int []> interact(
new int[cur_dim*cur_dim]);
182 for(
int a=0;a<cur_dim;a++)
184 auto bra =
spinbasis->getBlock(i).Get(a);
187 for(
int b=a;b<cur_dim;b++)
189 auto ket =
spinbasis->getBlock(i).Get(b);
191 interact[b+a*cur_dim] =
interaction(bra.first, bra.second, ket.first, ket.second);
192 interact[a+b*cur_dim] = interact[b+a*cur_dim];
196 int mydim =
spinbasis->getBlock(i).getdim();
197 std::unique_ptr<matrix> Jterm (
new matrix (mydim,mydim));
198 std::unique_ptr<matrix> Uterm (
new matrix (mydim,mydim));
200 auto &sparse =
spinbasis->getBlock(i).getSparse();
202 #pragma omp parallel for schedule(guided)
203 for(
int a=0;a<mydim;a++)
205 for(
int b=a;b<mydim;b++)
210 for(
int k=0;k<sparse.NumOfElInCol(a);k++)
211 for(
int l=0;l<sparse.NumOfElInCol(b);l++)
213 if(sparse.GetElementRowIndexInCol(a,k) == sparse.GetElementRowIndexInCol(b,l) )
214 (*Jterm)(a,b) += sparse.GetElementInCol(a,k) * sparse.GetElementInCol(b,l) * \
215 1 * hop[sparse.GetElementRowIndexInCol(a,k)];
217 (*Uterm)(a,b) += sparse.GetElementInCol(a,k) * sparse.GetElementInCol(b,l) * 1.0/
L * \
218 interact[sparse.GetElementRowIndexInCol(a,k) + cur_dim * sparse.GetElementRowIndexInCol(b,l)];
221 (*Jterm)(b,a) = (*Jterm)(a,b);
222 (*Uterm)(b,a) = (*Uterm)(a,b);
228 std::stringstream nameJ;
229 nameJ <<
"Jterm-" << K <<
"-" << S <<
".h5";
230 SaveToFile(nameJ.str(),Jterm->getpointer(), mydim*mydim);
232 std::stringstream nameU;
233 nameU <<
"Uterm-" << K <<
"-" << S <<
".h5";
234 SaveToFile(nameU.str(),Uterm->getpointer(), mydim*mydim);
258 myint k2sp = downket & (~downket + 1);
277 myint k1sp = upket & (~upket + 1);
292 myint k3sp = upbra & (~upbra + 1);
299 if(! ((c ^ k1sp) == (a ^ k3sp)) )
305 if(! ((1<<k4 & b) && ((d ^ k2sp) == (b ^ 1<<k4)) ))
318 result += signk1*signk2*signk3*signk4;
340 myint hop = ket & (~ket + 1);
344 result += -2* cos(2.0*M_PI/
L *
CountBits(hop-1));
368 dsymv_(&uplo,&dim,&beta,
blockmat[B]->getpointer(),&dim,&x[offset],&incx,&alpha,&y[offset],&incx);
389 std::vector<double> eigenvalues(mydim);
405 std::sort(eigenvalues.begin(), eigenvalues.end());
420 std::vector< std::tuple<int, int, double> > energy;
422 std::vector< std::tuple<int,int,class matrix> > eigs (
blockmat.size());
424 #pragma omp parallel for
439 eigs[B] = std::make_tuple(K, S, std::move(cur_eigs));
442 for(
int i=0;i<eigs.size();i++)
443 for(
int j=0;j<std::get<2>(eigs[i]).getn();j++)
444 energy.push_back(std::make_tuple(std::get<0>(eigs[i]), std::get<1>(eigs[i]), std::get<2>(eigs[i])[j]));
447 std::sort(energy.begin(), energy.end(),
448 [](
const std::tuple<int,int,double> & a,
const std::tuple<int,int,double> & b) ->
bool
450 return std::get<2>(a) < std::get<2>(b);
458 for(
int i=0;i<
spinbasis->getnumblocks();i++)
463 std::cout <<
"Block K=" << K <<
" S=" << S << std::endl;
474 int Smax = (
Nu+
Nd)/2;
482 int cur_Sz = (Su - Sd)/2;
485 std::unique_ptr<MomBasis> tmp_basis(
new MomBasis(
L,Su,Sd));
487 int tmp_k = ((
L-1)*
L)/2 %
L;
488 basis.
Create(tmp_k,cur_Sz,cur_Sz,*tmp_basis,tmp_basis->getdimK(tmp_k));
493 cur_Sz = (Su - Sd)/2;
495 basis.
Create(tmp_k,cur_Sz+1,cur_Sz,*tmp_basis, basis.
Get(tmp_k,cur_Sz+1,cur_Sz+1).
getdim());
496 basis.
Get(tmp_k,cur_Sz+1,cur_Sz).
Slad_min(basis.
Get(tmp_k,cur_Sz+1,cur_Sz+1));
498 basis.
Create(tmp_k,cur_Sz,cur_Sz,*tmp_basis,tmp_basis->getdimK(tmp_k) - basis.
Get(tmp_k,cur_Sz+1,cur_Sz).
getdim() );
503 basis.
Create(k,cur_Sz,cur_Sz,*tmp_basis,tmp_basis->getdimK(k));
505 basis.
Clean(cur_Sz+1);
510 cur_Sz = (Su - Sd)/2;
512 while( cur_Sz >=
Sz )
514 tmp_basis.reset(
new MomBasis(L,Su,Sd));
516 #pragma omp parallel for
519 int cur_dim = tmp_basis->getdimK(K);
521 for(
int cur_S=Smax;cur_S>cur_Sz;cur_S--)
525 std::cout <<
"At: Sz=" << cur_Sz <<
" K=" << K <<
" (" << cur_dim <<
") => S=" << cur_S << std::endl;
528 if(basis.
Exists(K,cur_S,cur_Sz+1))
530 basis.
Create(K,cur_S,cur_Sz,*tmp_basis,basis.
Get(K,cur_S,cur_Sz+1).
getdim());
532 cur_dim -= basis.
Get(K,cur_S,cur_Sz+1).
getdim();
539 std::cout <<
"Projection to K=" << K <<
" S=" << cur_Sz <<
" Sz=" << cur_Sz << std::endl;
541 basis.
Create(K,cur_Sz,cur_Sz,*tmp_basis,cur_dim);
546 basis.
Clean(cur_Sz+1);
550 cur_Sz = (Su - Sd)/2;
580 hid_t file_id, group_id, dataset_id, dataspace_id, attribute_id;
583 file_id = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
586 group_id = H5Gcreate(file_id,
"run", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
589 dataspace_id = H5Screate(H5S_SCALAR);
591 attribute_id = H5Acreate (group_id,
"L", H5T_STD_I32LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
592 status = H5Awrite (attribute_id, H5T_NATIVE_INT, &
L );
594 status = H5Aclose(attribute_id);
597 attribute_id = H5Acreate (group_id,
"Nu", H5T_STD_I32LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
598 status = H5Awrite (attribute_id, H5T_NATIVE_INT, &
Nu );
600 status = H5Aclose(attribute_id);
603 attribute_id = H5Acreate (group_id,
"Nd", H5T_STD_I32LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
604 status = H5Awrite (attribute_id, H5T_NATIVE_INT, &
Nd );
606 status = H5Aclose(attribute_id);
609 attribute_id = H5Acreate (group_id,
"J", H5T_IEEE_F64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
610 status = H5Awrite (attribute_id, H5T_NATIVE_DOUBLE, &
J );
612 status = H5Aclose(attribute_id);
615 attribute_id = H5Acreate (group_id,
"Ubegin", H5T_IEEE_F64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
616 status = H5Awrite (attribute_id, H5T_NATIVE_DOUBLE, &Ubegin );
618 status = H5Aclose(attribute_id);
621 attribute_id = H5Acreate (group_id,
"Uend", H5T_IEEE_F64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
622 status = H5Awrite (attribute_id, H5T_NATIVE_DOUBLE, &Uend );
624 status = H5Aclose(attribute_id);
627 attribute_id = H5Acreate (group_id,
"Ustep", H5T_IEEE_F64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
628 status = H5Awrite (attribute_id, H5T_NATIVE_DOUBLE, &step );
630 status = H5Aclose(attribute_id);
633 status = H5Sclose(dataspace_id);
636 status = H5Gclose(group_id);
639 status = H5Fclose(file_id);
642 std::vector< std::unique_ptr<double []> > all_eigs;
645 double Ucur = Ubegin;
649 std::cout <<
"U = " << Ucur << std::endl;
654 #pragma omp parallel for
659 std::unique_ptr<double []> eigs(
new double [mydim]);
663 all_eigs[B] = std::move(eigs);
667 std::stringstream name;
668 name << std::setprecision(5) << std::fixed <<
"/run/" << Ucur;
670 file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
673 U_id = H5Gcreate(file_id, name.str().c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
676 for(
int B=0;B<all_eigs.size();B++)
683 hsize_t dimarr = mydim;
685 dataspace_id = H5Screate_simple(1, &dimarr, NULL);
687 std::stringstream cur_block;
689 dataset_id = H5Dcreate(U_id, cur_block.str().c_str(), H5T_IEEE_F64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
691 status = H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, all_eigs[B].
get() );
694 status = H5Sclose(dataspace_id);
697 dataspace_id = H5Screate(H5S_SCALAR);
699 attribute_id = H5Acreate (dataset_id,
"K", H5T_STD_I32LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
700 status = H5Awrite (attribute_id, H5T_NATIVE_INT, &K );
702 status = H5Aclose(attribute_id);
705 attribute_id = H5Acreate (dataset_id,
"S", H5T_STD_I32LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
706 status = H5Awrite (attribute_id, H5T_NATIVE_INT, &S );
708 status = H5Aclose(attribute_id);
711 status = H5Dclose(dataset_id);
715 status = H5Gclose(U_id);
718 status = H5Fclose(file_id);