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: Bryan Clark, bclark@Princeton.edu, Princeton University
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
11 //
12 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
13 //////////////////////////////////////////////////////////////////////////////////////
14
15
16 #include "StructFact.h"
17 #include "config/stdlib/math.hpp"
18 #include "CPU/e2iphi.h"
19 #include "CPU/SIMD/vmath.hpp"
20 #include "CPU/BLAS.hpp"
21 #include "Utilities/qmc_common.h"
22
23 namespace qmcplusplus
24 {
25 //Constructor - pass arguments to KLists' constructor
StructFact(ParticleSet & P,RealType kc)26 StructFact::StructFact(ParticleSet& P, RealType kc)
27 : DoUpdate(false), StorePerParticle(false), SuperCellEnum(SUPERCELL_BULK)
28 {
29 if (qmc_common.use_ewald && P.LRBox.SuperCellEnum == SUPERCELL_SLAB)
30 {
31 app_log() << " Setting StructFact::SuperCellEnum=SUPERCELL_SLAB " << std::endl;
32 SuperCellEnum = SUPERCELL_SLAB;
33 }
34
35 UpdateNewCell(P, kc);
36 }
37
38 //Destructor
~StructFact()39 StructFact::~StructFact() {}
40
UpdateNewCell(ParticleSet & P,RealType kc)41 void StructFact::UpdateNewCell(ParticleSet& P, RealType kc)
42 {
43 //Generate the lists of k-vectors
44 KLists.UpdateKLists(P.LRBox, kc);
45 //resize any array
46 resize(P.getSpeciesSet().size(), P.getTotalNum(), KLists.numk);
47 //Compute the entire Rhok
48 FillRhok(P);
49 }
50
resize(int ns,int nptcl,int nkpts)51 void StructFact::resize(int ns, int nptcl, int nkpts)
52 {
53 phiV.resize(nkpts);
54 #if defined(USE_REAL_STRUCT_FACTOR)
55 rhok_r.resize(ns, nkpts);
56 rhok_i.resize(ns, nkpts);
57 if (StorePerParticle)
58 {
59 eikr_r.resize(nptcl, nkpts);
60 eikr_i.resize(nptcl, nkpts);
61 }
62 eikr_r_temp.resize(nkpts);
63 eikr_i_temp.resize(nkpts);
64 #else
65 rhok.resize(ns, nkpts);
66 eikr.resize(nptcl, nkpts);
67 eikr_temp.resize(nkpts);
68 #endif
69 }
70
71
UpdateAllPart(ParticleSet & P)72 void StructFact::UpdateAllPart(ParticleSet& P) { FillRhok(P); }
73
74
75 /** evaluate rok per species, eikr per particle
76 */
FillRhok(ParticleSet & P)77 void StructFact::FillRhok(ParticleSet& P)
78 {
79 int npart = P.getTotalNum();
80 #if defined(USE_REAL_STRUCT_FACTOR)
81 rhok_r = 0.0;
82 rhok_i = 0.0;
83 //algorithmA
84 const int nk = KLists.numk;
85 if (StorePerParticle)
86 {
87 // save per particle and species value
88 for (int i = 0; i < npart; ++i)
89 {
90 const auto& pos = P.R[i];
91 auto* restrict eikr_r_ptr = eikr_r[i];
92 auto* restrict eikr_i_ptr = eikr_i[i];
93 auto* restrict rhok_r_ptr = rhok_r[P.GroupID[i]];
94 auto* restrict rhok_i_ptr = rhok_i[P.GroupID[i]];
95 #pragma omp simd
96 for (int ki = 0; ki < nk; ki++)
97 {
98 qmcplusplus::sincos(dot(KLists.kpts_cart[ki], pos), &eikr_i_ptr[ki], &eikr_r_ptr[ki]);
99 rhok_r_ptr[ki] += eikr_r_ptr[ki];
100 rhok_i_ptr[ki] += eikr_i_ptr[ki];
101 }
102 }
103 }
104 else
105 {
106 // save per species value
107 for (int i = 0; i < npart; ++i)
108 {
109 const auto& pos = P.R[i];
110 auto* restrict rhok_r_ptr = rhok_r[P.GroupID[i]];
111 auto* restrict rhok_i_ptr = rhok_i[P.GroupID[i]];
112 #ifdef __INTEL_COMPILER
113 #pragma omp simd
114 for (int ki = 0; ki < nk; ki++)
115 {
116 RealType s, c;
117 qmcplusplus::sincos(dot(KLists.kpts_cart[ki], pos), &s, &c);
118 rhok_r_ptr[ki] += c;
119 rhok_i_ptr[ki] += s;
120 }
121 #else
122 for (int ki = 0; ki < nk; ki++)
123 phiV[ki] = dot(KLists.kpts_cart[ki], pos);
124 eval_e2iphi(nk, phiV.data(), eikr_r_temp.data(), eikr_i_temp.data());
125 for (int ki = 0; ki < nk; ki++)
126 {
127 rhok_r_ptr[ki] += eikr_r_temp[ki];
128 rhok_i_ptr[ki] += eikr_i_temp[ki];
129 }
130 #endif
131 }
132 }
133 #else
134 rhok = 0.0;
135 for (int i = 0; i < npart; i++)
136 {
137 PosType pos(P.R[i]);
138 RealType s, c; //get sin and cos
139 ComplexType* restrict eikr_ref = eikr[i];
140 ComplexType* restrict rhok_ref = rhok[P.GroupID[i]];
141 for (int ki = 0; ki < KLists.numk; ki++)
142 {
143 qmcplusplus::sincos(dot(KLists.kpts_cart[ki], pos), &s, &c);
144 eikr_ref[ki] = ComplexType(c, s);
145 rhok_ref[ki] += eikr_ref[ki];
146 }
147 }
148 #endif
149 }
150
151
makeMove(int active,const PosType & pos)152 void StructFact::makeMove(int active, const PosType& pos)
153 {
154 #if defined(USE_REAL_STRUCT_FACTOR)
155 #pragma omp simd
156 for (int ki = 0; ki < KLists.numk; ki++)
157 qmcplusplus::sincos(dot(KLists.kpts_cart[ki], pos), &eikr_i_temp[ki], &eikr_r_temp[ki]);
158 #else
159 RealType s, c; //get sin and cos
160 for (int ki = 0; ki < KLists.numk; ++ki)
161 {
162 qmcplusplus::sincos(dot(KLists.kpts_cart[ki], pos), &s, &c);
163 eikr_temp[ki] = ComplexType(c, s);
164 }
165 #endif
166 }
167
acceptMove(int active,int gid,const PosType & rold)168 void StructFact::acceptMove(int active, int gid, const PosType& rold)
169 {
170 #if defined(USE_REAL_STRUCT_FACTOR)
171 if (StorePerParticle)
172 {
173 RealType* restrict eikr_ptr_r = eikr_r[active];
174 RealType* restrict eikr_ptr_i = eikr_i[active];
175 RealType* restrict rhok_ptr_r(rhok_r[gid]);
176 RealType* restrict rhok_ptr_i(rhok_i[gid]);
177 for (int ki = 0; ki < KLists.numk; ++ki)
178 {
179 rhok_ptr_r[ki] += (eikr_r_temp[ki] - eikr_ptr_r[ki]);
180 rhok_ptr_i[ki] += (eikr_i_temp[ki] - eikr_ptr_i[ki]);
181 eikr_ptr_r[ki] = eikr_r_temp[ki];
182 eikr_ptr_i[ki] = eikr_i_temp[ki];
183 }
184 }
185 else
186 {
187 RealType* restrict rhok_ptr_r(rhok_r[gid]);
188 RealType* restrict rhok_ptr_i(rhok_i[gid]);
189
190 // add the new value and subtract the old value
191 #pragma omp simd
192 for (int ki = 0; ki < KLists.numk; ++ki)
193 {
194 RealType s, c;
195 qmcplusplus::sincos(dot(KLists.kpts_cart[ki], rold), &s, &c);
196 rhok_ptr_r[ki] += eikr_r_temp[ki] - c;
197 rhok_ptr_i[ki] += eikr_i_temp[ki] - s;
198 }
199 }
200 #else
201 ComplexType* restrict eikr_ptr = eikr[active];
202 ComplexType* restrict rhok_ptr(rhok[gid]);
203 for (int ki = 0; ki < KLists.numk; ++ki)
204 {
205 rhok_ptr[ki] += (eikr_temp[ki] - eikr_ptr[ki]);
206 eikr_ptr[ki] = eikr_temp[ki];
207 }
208 #endif
209 }
210
rejectMove(int active,int gid)211 void StructFact::rejectMove(int active, int gid)
212 {
213 //do nothing
214 }
215
turnOnStorePerParticle(ParticleSet & P)216 void StructFact::turnOnStorePerParticle(ParticleSet& P)
217 {
218 #if defined(USE_REAL_STRUCT_FACTOR)
219 if (!StorePerParticle)
220 {
221 StorePerParticle = true;
222 const int nptcl = P.getTotalNum();
223 eikr_r.resize(nptcl, KLists.numk);
224 eikr_i.resize(nptcl, KLists.numk);
225 FillRhok(P);
226 }
227 #endif
228 }
229
230 } // namespace qmcplusplus
231