JDFTx  1.2.0
VectorField.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------
2 Copyright 2011 Ravishankar Sundararaman
3 
4 This file is part of JDFTx.
5 
6 JDFTx is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10 
11 JDFTx is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with JDFTx. If not, see <http://www.gnu.org/licenses/>.
18 -------------------------------------------------------------------*/
19 
20 #ifndef JDFTX_CORE_VECTORFIELD_H
21 #define JDFTX_CORE_VECTORFIELD_H
22 
25 
30 #include <core/ScalarField.h>
31 #include <core/GridInfo.h>
32 #include <core/Operators.h>
33 #include <core/vector3.h>
34 #include <vector>
35 
36 #define Tptr std::shared_ptr<T>
37 #define TptrMul ScalarFieldMultiplet<T,N>
38 #define RptrMul ScalarFieldMultiplet<ScalarFieldData,N>
39 #define GptrMul ScalarFieldMultiplet<ScalarFieldTildeData,N>
40 
41 #define Nloop(code) for(int i=0; i<N; i++) {code} //loop over components (used repeatedly below)
43 
45 
49 template<class T, int N> struct ScalarFieldMultiplet
50 { std::vector<Tptr> component;
51 
54  ScalarFieldMultiplet(const Tptr* in=0) : component(N) { Nloop( component[i] = (in ? in[i] : 0); ) }
55 
58  ScalarFieldMultiplet(const GridInfo& gInfo, bool onGpu=false) : component(N) { Nloop( component[i] = Tptr(T::alloc(gInfo,onGpu)); ) }
59 
60  Tptr& operator[](int i) { return component[i]; }
61  const Tptr& operator[](int i) const { return component[i]; }
62  ScalarFieldMultiplet clone() const { TptrMul out; Nloop( out[i] = component[i]->clone(); ) return out; }
63 
64  std::vector<typename T::DataType*> data();
65  std::vector<const typename T::DataType*> data() const;
66  std::vector<const typename T::DataType*> const_data() const { return data(); }
67  #ifdef GPU_ENABLED
68  std::vector<typename T::DataType*> dataGpu();
69  std::vector<const typename T::DataType*> dataGpu() const;
70  std::vector<const typename T::DataType*> const_dataGpu() const { return dataGpu(); }
71  #endif
72 
73  //Preferred data access (on GPU if available, on CPU otherwise)
74  #ifdef GPU_ENABLED
75  std::vector<typename T::DataType*> dataPref() { return dataGpu(); }
76  std::vector<const typename T::DataType*> dataPref() const { return dataGpu(); }
77  std::vector<const typename T::DataType*> const_dataPref() const { return dataGpu(); }
78  #else
79  std::vector<typename T::DataType*> dataPref() { return data(); }
80  std::vector<const typename T::DataType*> dataPref() const { return data(); }
81  std::vector<const typename T::DataType*> const_dataPref() const { return data(); }
82  #endif
83 
84 
85  explicit operator bool() const { bool ret=true; Nloop(ret = ret && component[i];) return ret; }
86  void loadFromFile(const char* fileName);
87  void saveToFile(const char* fileName) const;
88 };
93 
94 //Allocation/init/copy etc:
95 template<class T,int N> TptrMul clone(const TptrMul& X) { return X ? X.clone() : (TptrMul)0; }
96 template<class T,int N> void initZero(TptrMul& X) { Nloop( initZero(X[i]); ) }
97 template<class T,int N> void nullToZero(TptrMul& X, const GridInfo& gInfo) { Nloop(nullToZero(X[i],gInfo);) }
98 template<int N> void initRandom(RptrMul& X, double cap=0.0) {Nloop(initRandom(X[i],cap);)}
99 template<int N> void initRandomFlat(RptrMul& X) {Nloop(initRandomFlat(X[i]);)}
100 template<int N> void randomize(RptrMul& X) { initRandom(X, 3.); }
101 
102 //Multiplication of commensurate multiplets
103 template<class T,int N> TptrMul& operator*=(TptrMul& in, const TptrMul& other) { Nloop(in[i]*=other[i];) return in; }
104 template<class T,int N> TptrMul operator*(const TptrMul& in1, const TptrMul& in2) { TptrMul out(in1.clone()); return out *= in2; }
105 template<class T,int N> TptrMul operator*(TptrMul&& in1, const TptrMul& in2) { return in1 *= in2; }
106 template<class T,int N> TptrMul operator*(const TptrMul& in2, TptrMul&& in1) { return in2 *= in1; }
107 template<class T,int N> TptrMul operator*(TptrMul&& in1, TptrMul&& in2) { return in1 *= in2; }
108 
109 //Multiplication of multiplets with singlets
110 template<class T,int N> TptrMul& operator*=(TptrMul& inM, const Tptr& inS) { Nloop(inM[i]*=inS;) return inM; }
111 template<class T,int N> TptrMul operator*(const TptrMul& inM, const Tptr& inS) { TptrMul out(inM.clone()); return out *= inS; }
112 template<class T,int N> TptrMul operator*(const Tptr& inS, const TptrMul& inM) { TptrMul out(inM.clone()); return out *= inS; }
113 template<class T,int N> TptrMul operator*(TptrMul&& inM, const Tptr& inS) { return inM *= inS; }
114 template<class T,int N> TptrMul operator*(const Tptr& inS, TptrMul&& inM) { return inM *= inS; }
115 
116 //Multiplication by scalars:
117 template<class T,int N> TptrMul& operator*=(TptrMul& in, double scaleFac) { Nloop(in[i]*=scaleFac;) return in; }
118 template<class T,int N> TptrMul operator*(const TptrMul& in, double scaleFac) { TptrMul out(in.clone()); return out *= scaleFac; }
119 template<class T,int N> TptrMul operator*(double scaleFac, const TptrMul& in) { TptrMul out(in.clone()); return out *= scaleFac; }
120 template<class T,int N> TptrMul operator*(TptrMul&& in, double scaleFac) { return in *= scaleFac; }
121 template<class T,int N> TptrMul operator*(double scaleFac, TptrMul&& in) { return in *= scaleFac; }
122 template<class T> ScalarFieldMultiplet<T,3> operator*(vector3<> v, const Tptr& in) { ScalarFieldMultiplet<T,3> out; for(int k=0; k<3; k++) out[k] = v[k] * in; return out; }
123 template<class T> Tptr dot(vector3<> v, const ScalarFieldMultiplet<T,3>& in) { Tptr out; for(int k=0; k<3; k++) out += v[k] * in[k]; return out; }
124 
125 //Linear combine operators:
126 template<class T,int N> void axpy(double alpha, const TptrMul& X, TptrMul& Y) { Nloop(axpy(alpha, X[i], Y[i]);) }
127 template<class T,int N> TptrMul& operator+=(TptrMul& in, const TptrMul& other) { axpy(+1.0, other, in); return in; }
128 template<class T,int N> TptrMul& operator-=(TptrMul& in, const TptrMul& other) { axpy(-1.0, other, in); return in; }
129 template<class T,int N> TptrMul operator+(const TptrMul& in1, const TptrMul& in2) { TptrMul out(in1.clone()); return out += in2; }
130 template<class T,int N> TptrMul operator+(const TptrMul& in1, TptrMul&& in2) { return in2 += in1; }
131 template<class T,int N> TptrMul operator+(TptrMul&& in1, const TptrMul& in2) { return in1 += in2; }
132 template<class T,int N> TptrMul operator+(TptrMul&& in1, TptrMul&& in2) { return in1 += in2; }
133 template<class T,int N> TptrMul operator-(const TptrMul& in1, const TptrMul& in2) { TptrMul out(in1.clone()); return out -= in2; }
134 template<class T,int N> TptrMul operator-(const TptrMul& in1, TptrMul&& in2) { return (in2 -= in1) *= -1.0; }
135 template<class T,int N> TptrMul operator-(TptrMul&& in1, const TptrMul& in2) { return in1 -= in2; }
136 template<class T,int N> TptrMul operator-(TptrMul&& in1, TptrMul&& in2) { return in1 -= in2; }
137 template<class T,int N> TptrMul operator-(const TptrMul& in) { return (-1.0)*in; }
138 template<class T,int N> TptrMul operator-(TptrMul&& in) { return in*=(-1.0); }
139 
140 //Linear combine with singlets:
141 template<class T,int N> void axpy(double alpha, const Tptr& X, TptrMul& Y) { Nloop(axpy(alpha, X, Y[i]);) }
142 template<class T,int N> TptrMul& operator+=(TptrMul& in, const Tptr& other) { axpy(+1.0, other, in); return in; }
143 template<class T,int N> TptrMul& operator-=(TptrMul& in, const Tptr& other) { axpy(-1.0, other, in); return in; }
144 template<class T,int N> TptrMul operator+(const TptrMul& in1, const Tptr& in2) { TptrMul out(in1.clone()); return out += in2; }
145 template<class T,int N> TptrMul operator+(const Tptr& in1, const TptrMul& in2) { TptrMul out(in2.clone()); return out += in1; }
146 template<class T,int N> TptrMul operator+(const Tptr& in1, TptrMul&& in2) { return in2 += in1; }
147 template<class T,int N> TptrMul operator+(TptrMul&& in1, const Tptr& in2) { return in1 += in2; }
148 template<class T,int N> TptrMul operator-(const TptrMul& in1, const Tptr& in2) { TptrMul out(in1.clone()); return out -= in2; }
149 template<class T,int N> TptrMul operator-(const Tptr& in1, const TptrMul& in2) { TptrMul out(in2.clone()); return (out -= in1) *= -1.0; }
150 template<class T,int N> TptrMul operator-(TptrMul&& in1, const Tptr& in2) { return in1 -= in2; }
151 template<class T,int N> TptrMul operator-(const Tptr& in1, TptrMul&& in2) { return (in2 -= in1) *= -1.0; }
152 
153 //Norms and dot products
154 template<class T,int N> double dot(const TptrMul& X, const TptrMul& Y) { double ret=0.0; Nloop(ret+=dot(X[i],Y[i]);) return ret; }
155 template<class T,int N> double nrm2(const TptrMul& X) { return sqrt(dot(X,X)); }
156 template<class T,int N> double sum(const TptrMul& X) { double ret=0.0; Nloop(ret+=sum(X[i]);) return ret; }
157 inline vector3<> getGzero(const VectorFieldTilde& X) { vector3<> ret; for(int k=0; k<3; k++) if(X[k]) ret[k]=X[k]->getGzero(); return ret; }
158 inline void setGzero(const VectorFieldTilde& X, vector3<> v) { for(int k=0; k<3; k++) if(X[k]) X[k]->setGzero(v[k]); }
159 inline vector3<> sumComponents(const VectorField& X) { return vector3<>(sum(X[0]), sum(X[1]), sum(X[2])); }
160 inline ScalarField lengthSquared(const VectorField& X) { return X[0]*X[0] + X[1]*X[1] + X[2]*X[2]; }
161 inline ScalarField dotElemwise(const VectorField& X, const VectorField& Y) { return X[0]*Y[0] + X[1]*Y[1] + X[2]*Y[2]; }
162 
163 //Extra operators in R-space alone for scalar additions:
164 template<int N> RptrMul& operator+=(RptrMul& in, double scalar) { Nloop(in[i]+=scalar;) return in; }
165 template<int N> RptrMul operator+(double scalar, const RptrMul& in) { RptrMul out(in.clone()); return out += scalar; }
166 template<int N> RptrMul operator+(const RptrMul& in, double scalar) { RptrMul out(in.clone()); return out += scalar; }
167 template<int N> RptrMul operator+(double scalar, RptrMul&& in) { return in += scalar; }
168 template<int N> RptrMul operator+(RptrMul&& in, double scalar) { return in += scalar; }
169 
170 //Extra operators in G-space alone for real kernel multiplications:
171 template<int N> GptrMul& operator*=(GptrMul& in, const RealKernel& kernel) { Nloop(in[i]*=kernel;) return in; }
172 template<int N> GptrMul operator*(const RealKernel& kernel, const GptrMul& in) { GptrMul out(in.clone()); return out *= kernel; }
173 template<int N> GptrMul operator*(const GptrMul& in, const RealKernel& kernel) { GptrMul out(in.clone()); return out *= kernel; }
174 template<int N> GptrMul operator*(const RealKernel& kernel, GptrMul&& in) { return in *= kernel; }
175 template<int N> GptrMul operator*(GptrMul&& in, const RealKernel& kernel) { return in *= kernel; }
176 
177 //Transform operators:
178 template<int N> GptrMul O(GptrMul&& X) { Nloop( O((ScalarFieldTilde&&)X[i]); ) return X; }
179 template<int N> GptrMul O(const GptrMul& X) { return O(X.clone()); }
180 template<int N> RptrMul I(GptrMul&& X, bool compat=false);
181 template<int N> GptrMul J(const RptrMul& X);
182 template<int N> GptrMul Idag(const RptrMul& X);
183 template<int N> RptrMul Jdag(GptrMul&& X, bool compat=false);
184 template<int N> RptrMul Jdag(const GptrMul& X, bool compat=false) { return Jdag(X.clone(), compat); }
185 template<int N> RptrMul I(const GptrMul& X, bool compat=false) { return I(X.clone(), compat); }
186 
187 //Special operators for triplets (implemented in operators.cpp):
188 VectorFieldTilde gradient(const ScalarFieldTilde&);
189 VectorField gradient(const ScalarField&);
190 ScalarFieldTilde divergence(const VectorFieldTilde&);
191 ScalarField divergence(const VectorField&);
192 
193 //Special operators for symmetric traceless tensors (implemented in operators.cpp)
194 TensorFieldTilde tensorGradient(const ScalarFieldTilde&);
195 ScalarFieldTilde tensorDivergence(const TensorFieldTilde&);
196 
197 //Debug:
198 template<int N> void printStats(const RptrMul&, const char* name, FILE* fpLog=stdout);
199 
201 
202 //###################################################################################################
203 //#### Implementation ####
204 //##########################
206 
207 template<class T, int N>
208 std::vector<typename T::DataType*> TptrMul::data()
209 { std::vector<typename T::DataType*> ret(N, (typename T::DataType*)0);
210  Nloop( if(component[i]) ret[i] = component[i]->data(); )
211  return ret;
212 }
213 template<class T, int N>
214 std::vector<const typename T::DataType*> TptrMul::data() const
215 { std::vector<const typename T::DataType*> ret(N, (const typename T::DataType*)0);
216  Nloop( if(component[i]) ret[i] = component[i]->data(); )
217  return ret;
218 }
219 #ifdef GPU_ENABLED
220 template<class T, int N>
221 std::vector<typename T::DataType*> TptrMul::dataGpu()
222 { std::vector<typename T::DataType*> ret(N, (typename T::DataType*)0);
223  Nloop( if(component[i]) ret[i] = component[i]->dataGpu(); )
224  return ret;
225 }
226 template<class T, int N>
227 std::vector<const typename T::DataType*> TptrMul::dataGpu() const
228 { std::vector<const typename T::DataType*> ret(N, (typename T::DataType*)0);
229  Nloop( if(component[i]) ret[i] = component[i]->dataGpu(); )
230  return ret;
231 }
232 #endif
233 
234 template<class T, int N>
235 void TptrMul::loadFromFile(const char* filename)
236 { //Checks for the correct filesize
237  off_t expectedLen = 0;
238  Nloop(expectedLen += sizeof(typename T::DataType) * component[i]->nElem;)
239  off_t fLen = fileSize(filename);
240  if(fLen != expectedLen)
241  { die("\nLength of '%s' was %ld instead of the expected %ld bytes.\n"
242  "Hint: Are you really reading the correct file?\n\n",
243  filename, (unsigned long)fLen, (unsigned long)expectedLen);
244  }
245 
246  FILE* fp = fopen(filename, "rb");
247  if(!fp) die("Could not open %s for reading.\n", filename)
248  Nloop(
249  if(!component[i]) die("Component %d was null in loadFromFile(\"%s\").\n", i, filename)
250  if(freadLE(component[i]->data(), sizeof(typename T::DataType), component[i]->nElem, fp) < unsigned(component[i]->nElem))
251  die("File ended too soon while reading component %d in loadFromFile(\"%s\").\n", i, filename)
252  )
253  fclose(fp);
254 }
255 template<class T, int N>
256 void TptrMul::saveToFile(const char* filename) const
257 { FILE* fp = fopen(filename, "wb");
258  if(!fp) die("Could not open %s for writing.\n", filename)
259  Nloop(
260  if(!component[i]) die("Component %d was null in saveToFile(\"%s\").\n", i, filename)
261  fwriteLE(component[i]->data(), sizeof(typename T::DataType), component[i]->nElem, fp);
262  )
263  fclose(fp);
264 }
265 
266 namespace ScalarFieldMultipletPrivate
267 {
268  inline ScalarField IcompatTrue(ScalarFieldTilde&& in, int nThreads) { return I((ScalarFieldTilde&&)in, true, nThreads); }
269  inline ScalarField IcompatFalse(ScalarFieldTilde&& in, int nThreads) { return I((ScalarFieldTilde&&)in, false, nThreads); }
270  inline ScalarField JdagCompatTrue(ScalarFieldTilde&& in, int nThreads) { return Jdag((ScalarFieldTilde&&)in, true, nThreads); }
271  inline ScalarField JdagCompatFalse(ScalarFieldTilde&& in, int nThreads) { return Jdag((ScalarFieldTilde&&)in, false, nThreads); }
272 
273  template<typename FuncOut, typename FuncIn, typename Out, typename In>
274  void threadUnary_sub(int iOpThread, int nOpThreads, int nThreadsTot, int N, FuncOut (*func)(FuncIn,int), Out* out, In in)
275  { //Divide jobs amongst operator threads:
276  int iStart = (iOpThread*N)/nOpThreads;
277  int iStop = ((iOpThread+1)*N)/nOpThreads;
278  //Divide total threads amongst operator threads:
279  int nThreads = ((iOpThread+1)*nThreadsTot)/nOpThreads - (iOpThread*nThreadsTot)/nOpThreads;
280  for(int i=iStart; i<iStop; i++)
281  (*out)[i] = func((FuncIn)in[i], nThreads);
282  }
283 
284  template<typename FuncOut, typename FuncIn, typename Out, typename In>
285  void threadUnary(FuncOut (*func)(FuncIn,int), int N, Out* out, In in)
286  { int nThreadsTot = (isGpuEnabled() || !shouldThreadOperators()) ? 1 : nProcsAvailable;
287  int nOperatorThreads = std::min(nThreadsTot, N);
288  threadLaunch(nOperatorThreads, threadUnary_sub<FuncOut,FuncIn,Out,In>, 0, nThreadsTot, N, func, out, in);
289  }
290 };
291 
292 template<int N>
293 RptrMul I(GptrMul&& X, bool compat)
294 { using namespace ScalarFieldMultipletPrivate;
295  RptrMul out;
296  ScalarField (*func)(ScalarFieldTilde&&,int) = compat ? IcompatTrue : IcompatFalse;
297  threadUnary<ScalarField,ScalarFieldTilde&&>(func, N, &out, X);
298  return out;
299 }
300 
301 template<int N>
302 GptrMul J(const RptrMul& X)
303 { using namespace ScalarFieldMultipletPrivate;
304  GptrMul out;
305  ScalarFieldTilde (*func)(const ScalarField&,int) = J;
306  threadUnary(func, N, &out, X);
307  return out;
308 }
309 
310 template<int N>
311 GptrMul Idag(const RptrMul& X)
312 { using namespace ScalarFieldMultipletPrivate;
313  GptrMul out;
314  ScalarFieldTilde (*func)(const ScalarField&,int) = Idag;
315  threadUnary(func, N, &out, X);
316  return out;
317 }
318 
319 template<int N>
320 RptrMul Jdag(GptrMul&& X, bool compat)
321 { using namespace ScalarFieldMultipletPrivate;
322  RptrMul out;
323  ScalarField (*func)(ScalarFieldTilde&&,int) = compat ? JdagCompatTrue : JdagCompatFalse;
324  threadUnary<ScalarField,ScalarFieldTilde&&>(func, N, &out, X);
325  return out;
326 }
327 
328 template<int N> void printStats(const RptrMul& X, const char* namePrefix, FILE* fpLog)
329 { char name[256];
330  Nloop( sprintf(name, "%s[%d]", namePrefix, i); printStats(X[i], name, fpLog); )
331 }
332 
333 #undef Tptr
334 #undef TptrMul
335 #undef RptrMul
336 #undef GptrMul
338 
339 #endif // JDFTX_CORE_VECTORFIELD_H
vector3 sumComponents(const VectorField &X)
Sum of elements (component-wise)
Definition: VectorField.h:159
void randomize(RptrMul &X)
alternate interface required by Minimizable
Definition: VectorField.h:100
ScalarField dotElemwise(const VectorField &X, const VectorField &Y)
Elementwise dot.
Definition: VectorField.h:161
GptrMul Idag(const RptrMul &X)
Forward transform transpose: Real space -> PW basis.
Tptr dot(vector3<> v, const ScalarFieldMultiplet< T, 3 > &in)
3-vector multiply
Definition: VectorField.h:123
ScalarField sqrt(const ScalarField &)
Elementwise square root (preserve input)
Simulation grid descriptor.
Definition: GridInfo.h:45
TensorFieldTilde tensorGradient(const ScalarFieldTilde &)
symmetric traceless tensor second derivative of a scalar field
void initRandom(RptrMul &X, double cap=0.0)
initialize element-wise with a unit-normal random number (with a cap if cap>0)
Definition: VectorField.h:98
#define GptrMul
shorthand for reciprocal-space-only template operators/functions (undef&#39;d at end of file) ...
Definition: VectorField.h:39
bool shouldThreadOperators()
void initZero(TptrMul &X)
Initialize data to 0 and scale factors to 1.
Definition: VectorField.h:96
double sum(const TptrMul &X)
Sum of elements.
Definition: VectorField.h:156
std::vector< typename T::DataType * > data()
Get the component data pointers in an std::vector.
TptrMul operator-(const TptrMul &in1, const TptrMul &in2)
Subtract (preserve input)
Definition: VectorField.h:133
std::shared_ptr< ScalarFieldTildeData > ScalarFieldTilde
A smart reference-counting pointer to ScalarFieldTildeData.
Definition: ScalarField.h:45
void loadFromFile(const char *fileName)
Load all components from a single binary file.
void setGzero(const VectorFieldTilde &X, vector3<> v)
set G=0 components
Definition: VectorField.h:158
void threadLaunch(int nThreads, Callable *func, size_t nJobs, Args...args)
A simple utility for running muliple threads.
const Tptr & operator[](int i) const
Retrieve a const reference to the i&#39;th component (no bound checks)
Definition: VectorField.h:61
off_t fileSize(const char *filename)
Get the size of a file.
size_t freadLE(void *ptr, size_t size, size_t nmemb, FILE *fp)
Read from a little-endian binary file, regardless of operating endianness.
ScalarFieldMultiplet< ScalarFieldData, 5 > TensorField
Symmetric traceless tensor: real space field.
Definition: VectorField.h:91
std::vector< const typename T::DataType * > const_data() const
Get the component data pointers in an std::vector (const version)
Definition: VectorField.h:66
ScalarFieldMultiplet< ScalarFieldTildeData, 5 > TensorFieldTilde
Symmetric traceless tensor: reciprocal space field.
Definition: VectorField.h:92
Real and complex scalar fields in real and reciprocal space.
ScalarField I(const ScalarFieldTilde &, bool compat=false, int nThreads=0)
Forward transform: PW basis -> real space (preserve input)
vector3 getGzero(const VectorFieldTilde &X)
return G=0 components
Definition: VectorField.h:157
void saveToFile(const char *fileName) const
Save all components from a single binary file.
#define RptrMul
shorthand for real-space-only template operators/functions (undef&#39;d at end of file) ...
Definition: VectorField.h:38
VectorFieldTilde gradient(const ScalarFieldTilde &)
compute the gradient of a complex field, returns cartesian components
TptrMul operator*(const TptrMul &in1, const TptrMul &in2)
Elementwise multiply each component (preserve inputs)
Definition: VectorField.h:104
ScalarFieldTilde O(const ScalarFieldTilde &)
Inner product operator (diagonal in PW basis)
ScalarField lengthSquared(const VectorField &X)
Elementwise length squared.
Definition: VectorField.h:160
RptrMul Jdag(GptrMul &&X, bool compat=false)
Inverse transform transpose: PW basis -> real space (destructible input)
ScalarFieldMultiplet(const GridInfo &gInfo, bool onGpu=false)
Construct a multiplet with allocated data.
Definition: VectorField.h:58
void initRandomFlat(RptrMul &X)
initialize element-wise with a unit-flat [0:1) random number
Definition: VectorField.h:99
std::vector< const typename T::DataType * > const_dataGpu() const
Get the component GPU data pointers in an std::vector (const version)
Definition: VectorField.h:70
size_t fwriteLE(const void *ptr, size_t size, size_t nmemb, FILE *fp)
Write to a little-endian binary file, regardless of operating endianness.
void axpy(double alpha, const TptrMul &X, TptrMul &Y)
Linear combine Y += alpha * X.
Definition: VectorField.h:126
#define die(...)
Quit with an error message (formatted using printf()). Must be called from all processes.
Definition: Util.h:114
ScalarFieldMultiplet(const Tptr *in=0)
Construct multiplet from an array of data sets (or default: initialize to null)
Definition: VectorField.h:54
TptrMul & operator+=(TptrMul &in, const TptrMul &other)
Increment.
Definition: VectorField.h:127
void printStats(const RptrMul &, const char *name, FILE *fpLog=stdout)
Print mean and standard deviation of each component array with specified name (debug utility) ...
double nrm2(const TptrMul &X)
2-norm
Definition: VectorField.h:155
int nProcsAvailable
number of available processors (initialized to number of online processors, can be overriden) ...
Geometry of the simulation grid.
#define Tptr
shorthand for writing the template operators (undef&#39;d at end of header)
Definition: VectorField.h:36
GptrMul J(const RptrMul &X)
Inverse transform: Real space -> PW basis.
Special class for storing real reciprocal-space kernels encountered ever so often for convolutions...
Definition: ScalarField.h:180
ScalarFieldMultiplet< ScalarFieldTildeData, 3 > VectorFieldTilde
Reciprocal space vector field.
Definition: VectorField.h:90
ScalarFieldMultiplet< ScalarFieldData, 3 > VectorField
Real space vector field.
Definition: VectorField.h:89
TptrMul & operator*=(TptrMul &in, const TptrMul &other)
Elementwise multiply each component.
Definition: VectorField.h:103
ScalarFieldTilde divergence(const VectorFieldTilde &)
compute the divergence of a vector field specified in cartesian components
TptrMul operator+(const TptrMul &in1, const TptrMul &in2)
Add (preserve inputs)
Definition: VectorField.h:129
std::shared_ptr< ScalarFieldData > ScalarField
A smart reference-counting pointer to ScalarFieldData.
Definition: ScalarField.h:41
TptrMul & operator-=(TptrMul &in, const TptrMul &other)
Decrement.
Definition: VectorField.h:128
ScalarFieldMultiplet clone() const
Clone data (note assignment will be reference for the actual data)
Definition: VectorField.h:62
void nullToZero(TptrMul &X, const GridInfo &gInfo)
Allocate and initialize each component of X to 0 if null.
Definition: VectorField.h:97
std::vector< typename T::DataType * > dataGpu()
Get the component GPU data pointers in an std::vector.
Generic multiplet object with overloaded arithmetic.
Definition: VectorField.h:49
ScalarFieldTilde tensorDivergence(const TensorFieldTilde &)
second derivative contraction of a symmetric traceless tensor field
Operators on ScalarField&#39;s and ScalarFieldTilde&#39;s.
std::vector< Tptr > component
the array of components (also accessible via operator[])
Definition: VectorField.h:50
#define TptrMul
shorthand for the template operators/functions (undef&#39;d at end of file)
Definition: VectorField.h:37