# How to make a generic BosonSiteSet?

+1 vote

Dear all,

I want to make a BosonSiteSet with site number = N, but I would like to set a different local basis. for example, first site basis number: $MaxOcc[1] = 4$, the last basis number: $MaxOcc[N] = 4$, other sites basis number:$MaxOcc = 10$. Is there have a direct way to make this?

Best,
Meng

commented by (480 points)
edited
Hi Meng,

Not a complete answer, but if you look at the documentation for the boson.h file (https://github.com/ITensor/ITensor/blob/v3/itensor/mps/sites/boson.h ), you can see some things that should be modifiable.
Lines 52-57:
auto qints = Index::qnstorage(1+maxOcc);
for(int dummyn : range(1+maxOcc))
{
qints[dummyn ] = QNInt(QN({"Nb",dummyn}),1);
}
s = Index(std::move(qints),tags);

You can adjust those lines to use a different maxOcc for say sites 1,L and a different maxOcc for sites 2, 3, ..., L-1.

Nesting those lines inside of an if-then structure that allows you to chose between sites 1, L, or the rest. If you're new to C++ (like I am), note that the n or the site number on the boson.h file is different from the n in the for loop (to my knowledge, anyway), for that reason I adjusted the n in the for loop code pasted here to dummyn to make this easier to see what's going on in that boson.h file. The for loop's dummyn only exists inside of that for loop. The scoping of variables may be different than you're accustomed to, depending on which language you use most frequently. Carefully going through that boson.h file,  the documentation for quantum numbers, and  and comparing with some of the examples on here.

Hi Meng,

This is untested, but adapting the itensor/mps/sites/boson.h file with some additional arguments and if-thens like I suggested in the comment above should work to implement this. Below I've given some sample code for changing the inside of the boson.h file from ITensor. I've changed a couple variable named compared the the boson.h file to help remove any human confusion in variable scoping inside/outside the for loops (something I dislike about C++ vs. old-fashioned Fortran). So copy-pasting the boson.h to a new file, call it say, bosonfirstlast.h, then changing the middle section of code should mostly work with some adjustments as needed. When I made a custom site set for a problem with fermions that I'm working on, I had to rename some things, you may have similar compiler issues. Make sure to include your new .h file in your .cc code.

Changing the inside of the BosonSite{ ... } section of the code should allow for the flexibility of changing the maximum occupancy on the first and last sites (if those arguments aren't given, they should default to the bulk maximum occupancy).

The code below takes the usual inputs for bosons, with additional inputs for the finalsiteindex, and the different occupancies for the first and final sites.

BosonSite(Args const& args = Args::global())
{
auto conserveQNs = args.getBool("ConserveQNs",true);
auto conserveNb = args.getBool("ConserveNb",conserveQNs);

auto tags = TagSet("Site,Boson");
auto n = 1;
if(args.defined("SiteNumber") )
{
siteNumber = args.getInt("SiteNumber");
}

auto maxOcc = args.getInt("MaxOcc",1);
auto maxOcc1 = args.getInt("MaxOcc1",maxOcc);
auto maxOccL = args.getInt("MaxOccL",maxOcc);
auto finalsiteindex = args.getInt("finalsiteindex",1);
if(conserveQNs)
{
if(conserveNb)
{
if( siteNumber == 1)
{
auto qints = Index::qnstorage(1+maxOcc1);
for(int dummyn : range(1+maxOcc1))
{
qints[dummyn] = QNInt(QN({"Nb",dummyn}),1);
}
s = Index(std::move(qints),tags);
}
else if ( siteNumber == finalsiteindex )
{
auto qints = Index::qnstorage(1+maxOccL);
for(int dummyn : range(1+maxOccL))
{
qints[dummyn] = QNInt(QN({"Nb",dummyn}),1);
}
s = Index(std::move(qints),tags);
}
else // Site that is not at one edge or the other
{
auto qints = Index::qnstorage(1+maxOcc);
for(int dummyn : range(1+maxOcc))
{
qints[dummyn] = QNInt(QN({"Nb",dummyn}),1);
}
s = Index(std::move(qints),tags);
}

}
else
{
s = Index(QN(),1+maxOcc,tags);
}
}
else
{
if(conserveNb) throw ITError("ConserveNb cannot be true when ConserveQNs=false");
s = Index(1+maxOcc,tags);
}
}

commented by (260 points)
edited by
Hi JaredEBland,

Thank you very much share me this approach, this is a nice way to obtain what I wanted.

I currently come up with another idea, just for discussion:
I found there has a function named merge, in /itensor/mps/siteset.h. Applying this function we can construct arbitrary  siteset, take an example:
auto sites1 = Boson(l1,{"ConserveQNs",false,"MaxOcc=",nb1});
auto sites2 = Boson(l2,{"ConserveQNs",false,"MaxOcc=",nb2});
auto sites3 = merge(sites1,sites2,{"Start1=",1,"End1=",l1,"Start2=",1,"End2=",l2});
auto sites4 = Boson(l3,{"ConserveQNs",false,"MaxOcc=",nb3});
auto sites = merge(sites3,sites4,{"Start1=",1,"End1=",l1+l2,"Start2=",1,"End2=",l3});

With the above steps, sites1, sites2, and sites4 with different properties have been merged into a new one.
commented by (480 points)
Hi Meng,

I haven't used the merge function for creating alternative SiteSets, so I can't comment on it in detail, but I'm not sure what you mean by the term "local property" in this context. Do you mean that local interactions stay localized? Or are you referring to something else?
commented by (260 points)
Hi JaredEBland,

I just wanted to say one can set a series of SiteSet depending on the interest problem, for example, the combination of BosonSiteSet, FermiSiteSet, SpinSiteSet. Using the "merge" function, one can merge all SiteSets into one.
commented by (480 points)
Hi Meng,

I agree that that is interesting, but I *think* that if you want this on every site, the MixedSiteSet may be a faster way to combine several types of objects. There is some documentation here http://itensor.org/docs.cgi?vers=cppv3&page=formulas/gs_holst_polaron for a Fermion/Boson example, and a mixedspin.cc file that combines spin-1 and spin-1/2 in the sample sub-directory of ITensor. I also haven't used that yet, but there are a couple of questions on this forum that use it.
commented by (260 points)
Hi JaredEBland,

Sure! I have tried to modify the code of MixedSiteSet as I wanted but failed. Since I'm not familiar with ITensor. I would be very appreciated if you could help me~~
commented by (480 points)
Hi Meng,
I'm afraid that this is beyond my depth in ITensor. Perhaps one of the ITensor folks will answer this. But if you get the functionality you need using the adapted boson.h file like I suggested above, I'd just use whichever works and gives the functionality you need. If you have a system of something other than just bosons, you should probably open a new question to help people who search for a similar thing.

Jared
commented by (260 points)
Hi Jared,

Thank you for all! I will open a new question to ask for help!
commented by (480 points)
Happy to help to the extent that I can. Good luck!
commented by (70.1k points)
Thanks for helping, Jared. Much appreciated and I would be very glad to see more of users supporting other users on the site.

HEOM-ITensor: if you have an additional question or questions about this, please do post a new question as it would be easier to re-start the discussion that way from your current state of progress