1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Brett Van Der Goetz, bvdg@berkeley.edu, University of California at Berkeley
8 //
9 // File created by: Brett Van Der Goetz, bvdg@berkeley.edu, University of California at Berkeley
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #include <iostream>
13 #include "CountingJastrowBuilder.h"
14 #include "Utilities/ProgressReportEngine.h"
15 #include "OhmmsData/AttributeSet.h"
16 #include "QMCWaveFunctions/Jastrow/CountingJastrow.h"
17 
18 namespace qmcplusplus
19 {
CountingJastrowBuilder(Communicate * comm,ParticleSet & target,ParticleSet & source)20 CountingJastrowBuilder::CountingJastrowBuilder(Communicate *comm, ParticleSet& target, ParticleSet& source)
21     : WaveFunctionComponentBuilder(comm, target), SourcePtcl(&source)
22 {
23   ClassName = "CountingJastrowBuilder";
24   NameOpt   = "0";
25   TypeOpt   = "Counting";
26   RegionOpt = "voronoi";
27   SourceOpt = SourcePtcl->getName();
28 }
29 
CountingJastrowBuilder(Communicate * comm,ParticleSet & target)30 CountingJastrowBuilder::CountingJastrowBuilder(Communicate *comm, ParticleSet& target)
31     : WaveFunctionComponentBuilder(comm, target)
32 {
33   ClassName = "CountingJastrowBuilder";
34   NameOpt   = "0";
35   TypeOpt   = "Counting";
36   RegionOpt = "normalized_gaussian";
37   SourceOpt = "none";
38   SourcePtcl = NULL;
39 }
40 
createCJ(xmlNodePtr cur)41 WaveFunctionComponent* CountingJastrowBuilder::createCJ(xmlNodePtr cur)
42 {
43   ReportEngine PRE(ClassName, "createCJ(xmlNodePtr)");
44   using RegionType    = CountingGaussianRegion;
45   using FunctorType   = CountingGaussian;
46   using CJOrbitalType = CountingJastrow<RegionType>;
47 
48   SpeciesSet& species(targetPtcl.getSpeciesSet());
49 
50   auto* C = new RegionType(targetPtcl);
51 
52   Matrix<RealType> F;
53   bool opt_C = true, opt_F = true;
54   bool debug_flag = false;
55   int period = 0, seqlen = 0;
56 
57   // standard child loop
58   cur = cur->xmlChildrenNode;
59   while (cur != NULL)
60   {
61     std::string cname((const char*)cur->name);
62     // create counting region, populate with functions
63     if (cname == "region")
64     {
65       // read in opt_C option
66       OhmmsAttributeSet oAttrib;
67       std::string opt = "true";
68       std::string type = RegionOpt;
69       oAttrib.add(opt,  "opt");
70       oAttrib.add(type, "type");
71       oAttrib.put(cur);
72       opt_C = (opt == "true" || opt == "yes");
73       // add based on <function /> tags
74       xmlNodePtr cur2 = cur->xmlChildrenNode;
75       if(type == "normalized_gaussian")
76       {
77         while (cur2 != NULL)
78         {
79           std::string cname2((const char*)cur2->name);
80           if (cname2 == "function")
81           {
82             // read id
83             std::string fid;
84             OhmmsAttributeSet oAttrib2;
85             oAttrib2.add(fid, "id");
86             oAttrib2.put(cur2);
87             // get functor, add to function
88             FunctorType* func = new FunctorType(fid);
89             func->put(cur2);
90             C->addFunc(func, fid);
91           }
92           cur2 = cur2->next;
93         }
94       }
95       // add functions based on source
96       else if (type == "voronoi")
97       {
98         RealType alpha = 1.0;
99         while (cur2 != NULL)
100         {
101           std::string cname2((const char*)cur2->name);
102           if (cname2 == "var")
103           {
104             // read id
105             std::string vname;
106             OhmmsAttributeSet oAttrib2;
107             oAttrib2.add(vname, "name");
108             oAttrib2.put(cur2);
109             if(vname == "alpha")
110             {
111               putContent(alpha, cur2);
112             }
113           }
114           cur2 = cur2->next;
115         }
116         // read in source
117         if(SourcePtcl == NULL)
118         {
119           // quit with error - need a valid source
120         }
121         std::ostringstream os;
122         // add a function for each source particle
123         for(int i = 0; i < SourcePtcl->R.size(); ++i)
124         {
125           PosType gr = SourcePtcl->R[i];
126           bool opt_g = opt_C && (i != 0);
127           os.str("");
128           os << "g" << i;
129           std::string fid = os.str();
130           FunctorType* func = new FunctorType(fid, alpha, gr, opt_g);
131           C->addFunc(func, fid);
132         }
133         // set default F value to all zeroes with appropriate dimension
134         if(F.size() == 0)
135         {
136           int Fdim = SourcePtcl->R.size();
137           F.resize(Fdim, Fdim);
138           for(int I = 0; I < Fdim; ++I)
139             for(int J = 0; J < Fdim; ++J)
140               F(I,J) = 0;
141         }
142       }
143       // read in the counting region
144       C->put(cur);
145     }
146     if (cname == "var")
147     {
148       OhmmsAttributeSet oAttrib;
149       std::string namestr = "none";
150       oAttrib.add(namestr, "name");
151       oAttrib.put(cur);
152       if (namestr == "F")
153       {
154         // read in opt_F option and form
155         std::string form = "upper_triang";
156         std::string opt  = "true";
157         OhmmsAttributeSet rAttrib2;
158         rAttrib2.add(opt, "opt");
159         rAttrib2.add(form, "form");
160         rAttrib2.put(cur);
161         opt_F = (opt == "yes" || opt == "true");
162         // read in F matrix
163         if (form == "upper_triang")
164         {
165           // read in upper triangle, set dimension
166           std::vector<RealType> F_utri;
167           putContent(F_utri, cur);
168           int Fdim = (std::sqrt(8 * F_utri.size() + 1) - 1) / 2;
169 
170           if (!(F_utri.size() == Fdim * (Fdim + 1) / 2))
171           {
172             std::ostringstream err;
173             err << "CountingJastrow::put: F needs to be the upper-triangular component of a square matrix: "
174                 << F_utri.size() << " != " << Fdim * (Fdim + 1) / 2 << std::endl;
175             APP_ABORT(err.str());
176           }
177           // set F from upper triangular elements
178           F.resize(Fdim, Fdim);
179           auto it = F_utri.begin();
180           for (int I = 0; I < Fdim; ++I)
181             for (int J = I; J < Fdim; ++J, ++it)
182               F(I, J) = F(J, I) = (*it);
183         }
184         else if (form == "full_matrix")
185           putContent(F, cur);
186 
187         // transform the F matrix to put a zero in the lower-right corner
188 
189         RealType x = F(F.rows()-1, F.cols()-1);
190         for(int I = 0; I < F.rows(); ++I)
191           for(int J = 0; J < F.cols(); ++J)
192             F(I,J) -= x;
193       }
194       if (namestr == "debug")
195       {
196         // read in debug options
197         OhmmsAttributeSet rAttrib2;
198         debug_flag = true;
199         rAttrib2.add(period, "period");
200         rAttrib2.add(seqlen, "seqlen");
201         rAttrib2.put(cur);
202       }
203     }
204     cur = cur->next;
205   }
206   auto* CJ = new CJOrbitalType(targetPtcl, C, F);
207 
208   CJ->addDebug(debug_flag, seqlen, period);
209   CJ->addOpt(opt_C, opt_F);
210   CJ->setOptimizable(opt_C || opt_F);
211   CJ->initialize();
212   CJ->reportStatus(app_log());
213 
214   return CJ;
215 }
216 
buildComponent(xmlNodePtr cur)217 WaveFunctionComponent* CountingJastrowBuilder::buildComponent(xmlNodePtr cur)
218 {
219   OhmmsAttributeSet oAttrib;
220   oAttrib.add(RegionOpt, "region");
221   oAttrib.add(TypeOpt, "type");
222   oAttrib.add(NameOpt, "name");
223   oAttrib.put(cur);
224   return createCJ(cur);
225 }
226 
227 } // namespace qmcplusplus
228