JDFTx  1.2.0
ScalarFieldArray.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------
2 Copyright 2011 Ravishankar Sundararaman, Deniz Gunceler
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_SCALARFIELDARRAY_H
21 #define JDFTX_CORE_SCALARFIELDARRAY_H
22 
23 
26 
27 #include <core/VectorField.h>
28 #include <vector>
29 
30 #include <cstdio>
31 
32 typedef std::vector<ScalarField> ScalarFieldArray;
33 typedef std::vector<ScalarFieldTilde> ScalarFieldTildeArray;
34 #define TptrCollection std::vector<std::shared_ptr<T> >
35 
36 template<typename T> std::vector<typename T::DataType*> dataPref(TptrCollection& x)
38 { std::vector<typename T::DataType*> xData(x.size());
39  for(unsigned s=0; s<x.size(); s++)
40  xData[s] = x[s] ? x[s]->dataPref() : 0;
41  return xData;
42 }
43 
45 template<typename T> std::vector<const typename T::DataType*> constDataPref(const TptrCollection& x)
46 { std::vector<const typename T::DataType*> xData(x.size());
47  for(unsigned s=0; s<x.size(); s++)
48  xData[s] = x[s] ? x[s]->dataPref() : 0;
49  return xData;
50 }
51 
53 template<typename T> TptrCollection clone(const TptrCollection& x)
54 { TptrCollection ret(x.size());
55  for(unsigned i=0; i<x.size(); i++) if(x[i]) ret[i] = clone(x[i]);
56  return ret;
57 }
58 
60 template<typename T> TptrCollection& operator*=(TptrCollection& x, double alpha)
61 { for(unsigned i=0; i<x.size(); i++) if(x[i]) x[i] *= alpha;
62  return x;
63 }
64 template<class T> TptrCollection operator*(const TptrCollection& in, double scaleFac) {
65  TptrCollection out(clone(in)); return out *= scaleFac;
66 }
67 template<class T> TptrCollection operator*(double scaleFac, const TptrCollection& in) {
68  TptrCollection out(clone(in)); return out *= scaleFac;
69 }
70 template<class T> TptrCollection operator*(TptrCollection&& in, double scaleFac) { return in *= scaleFac; }
71 template<class T> TptrCollection operator*(double scaleFac, TptrCollection&& in) { return in *= scaleFac; }
72 
74 template<typename T> void axpy(double alpha, const TptrCollection& x, TptrCollection& y)
75 { assert(x.size()==y.size());
76  for(unsigned i=0; i<x.size(); i++) axpy(alpha, x[i], y[i]);
77 }
78 
81 { assert(x.size()==y.size());
82  ScalarFieldArray z(x.size());
83  for(unsigned i=0; i<x.size(); i++) z[i] = x[i]*y[i];
84  return z;
85 }
87 { assert(x.size()==y.size());
88  for(unsigned i=0; i<x.size(); i++) x[i] *= y[i];
89  return x;
90 }
92 { assert(x.size()==y.size());
93  for(unsigned i=0; i<x.size(); i++) y[i] *= x[i];
94  return y;
95 }
96 
98 { for(unsigned i=0; i<y.size(); i++) if(y[i]) y[i] *= x;
99  return y;
100 }
101 inline ScalarFieldArray operator*(const ScalarField& x, ScalarFieldArray&& y) { return y *= x; }
102 inline ScalarFieldArray operator*(ScalarFieldArray&& y, const ScalarField& x) { return y *= x; }
103 inline ScalarFieldArray operator*(const ScalarField& x, const ScalarFieldArray& y) { ScalarFieldArray z = clone(y); return z *= x; }
104 inline ScalarFieldArray operator*(const ScalarFieldArray& y, const ScalarField& x) { ScalarFieldArray z = clone(y); return z *= x; }
105 
107 template<class T> TptrCollection& operator+=(TptrCollection& in, const TptrCollection& other) { axpy(+1.0, other, in); return in; }
109 template<class T> TptrCollection& operator-=(TptrCollection& in, const TptrCollection& other) { axpy(-1.0, other, in); return in; }
110 
111 // Addition
112 template<class T> TptrCollection operator+(const TptrCollection& in1, const TptrCollection& in2) {
113  TptrCollection out(clone(in1));
114  return out += in2;
115 }
116 template<class T> TptrCollection operator+(const TptrCollection& in1, TptrCollection&& in2) { return in2 += in1; }
117 template<class T> TptrCollection operator+(TptrCollection&& in1, const TptrCollection& in2) { return in1 += in2; }
118 template<class T> TptrCollection operator+(TptrCollection&& in1, TptrCollection&& in2) { return in1 += in2; }
119 
120 // Subtraction
121 template<class T> TptrCollection operator-(const TptrCollection& in1, const TptrCollection& in2) {
122  TptrCollection out(clone(in1));
123  return out -= in2;
124 }
125 template<class T> TptrCollection operator-(const TptrCollection& in1, TptrCollection&& in2) { return in2 -= in1; }
126 template<class T> TptrCollection operator-(TptrCollection&& in1, const TptrCollection& in2) { return in1 -= in2; }
127 template<class T> TptrCollection operator-(TptrCollection&& in1, TptrCollection&& in2) { return in1 -= in2; }
128 
130 template<typename T> double dot(const TptrCollection& x, const TptrCollection& y)
131 { assert(x.size()==y.size());
132  double ret = 0.0;
133  for(unsigned i=0; i<x.size(); i++) if(x[i] && y[i]) ret += dot(x[i], y[i]);
134  return ret;
135 }
136 
138 template<typename T> void initZero(TptrCollection& x)
139 { for(unsigned i=0; i<x.size(); i++) initZero(x[i]);
140 }
141 
144 template<typename T> void nullToZero(TptrCollection& x, const GridInfo& gInfo, int N=0)
145 { if(N) x.resize(N);
146  for(unsigned i=0; i<x.size(); i++) nullToZero(x[i], gInfo);
147 }
148 
150 template<typename T> void initRandomFlat(TptrCollection& x)
151 { for(unsigned i=0; i<x.size(); i++) initRandomFlat(x[i]);
152 }
154 template<typename T> void randomize(TptrCollection& x)
155 { for(unsigned i=0; i<x.size(); i++) initRandom(x[i], 3.0);
156 }
157 
158 template<typename T> void loadFromFile(TptrCollection& x, const char* filename)
159 { //Checks for the correct filesize
160  off_t expectedLen = 0;
161  for(unsigned i=0; i<x.size(); i++){expectedLen += sizeof(typename T::DataType) * x[i]->nElem;}
162  off_t fLen = fileSize(filename);
163  if(fLen != expectedLen)
164  { die("\nLength of '%s' was %ld instead of the expected %ld bytes.\n"
165  "Hint: Are you really reading the correct file?\n\n",
166  filename, (unsigned long)fLen, (unsigned long)expectedLen);
167  }
168 
169  FILE* fp = fopen(filename, "rb");
170  if(!fp) die("Could not open %s for reading.\n", filename)
171  for(unsigned i=0; i<x.size(); i++)
172  { if(!x[i]) die("x[%d] was null in loadFromFile(x,\"%s\").\n", i, filename)
173  if(freadLE(x[i]->data(), sizeof(typename T::DataType), x[i]->nElem, fp) < unsigned(x[i]->nElem))
174  die("File ended too soon while reading x[%d] in loadFromFile(x,\"%s\").\n", i, filename)
175  }
176  fclose(fp);
177 }
178 
179 template<typename T> void saveToFile(const TptrCollection& x, const char* filename)
180 { FILE* fp = fopen(filename, "wb");
181  if(!fp) die("Could not open %s for writing.\n", filename)
182  for(unsigned i=0; i<x.size(); i++)
183  { if(!x[i]) die("x[%d] was null in saveToFile(x,\"%s\").\n", i, filename)
184  fwriteLE(x[i]->data(), sizeof(typename T::DataType), x[i]->nElem, fp);
185  }
186  fclose(fp);
187 }
188 
189 //----------------- Transform operators -------------------------
190 
191 inline ScalarFieldArray I(ScalarFieldTildeArray&& X, bool compat=false)
192 { using namespace ScalarFieldMultipletPrivate;
193  ScalarFieldArray out(X.size());
194  ScalarField (*func)(ScalarFieldTilde&&,int) = compat ? IcompatTrue : IcompatFalse;
195  threadUnary<ScalarField,ScalarFieldTilde&&>(func, int(X.size()), &out, X);
196  return out;
197 }
198 inline ScalarFieldArray I(const ScalarFieldTildeArray& X, bool compat=false) { return I(clone(X), compat); }
199 
201 { using namespace ScalarFieldMultipletPrivate;
202  ScalarFieldTildeArray out(X.size());
203  ScalarFieldTilde (*func)(const ScalarField&,int) = J;
204  threadUnary(func, int(X.size()), &out, X);
205  return out;
206 }
207 
209 { using namespace ScalarFieldMultipletPrivate;
210  ScalarFieldTildeArray out(X.size());
211  ScalarFieldTilde (*func)(const ScalarField&,int) = Idag;
212  threadUnary(func, int(X.size()), &out, X);
213  return out;
214 }
215 
216 inline ScalarFieldArray Jdag(ScalarFieldTildeArray&& X, bool compat=false)
217 { using namespace ScalarFieldMultipletPrivate;
218  ScalarFieldArray out(X.size());
219  ScalarField (*func)(ScalarFieldTilde&&,int) = compat ? JdagCompatTrue : JdagCompatFalse;
220  threadUnary<ScalarField,ScalarFieldTilde&&>(func, int(X.size()), &out, X);
221  return out;
222 }
223 inline ScalarFieldArray Jdag(const ScalarFieldTildeArray& X, bool compat=false) { return Jdag(clone(X), compat); }
224 
225 #undef TptrCollection
226 #endif // JDFTX_CORE_SCALARFIELDARRAY_H
ScalarFieldTilde Idag(const ScalarField &, int nThreads=0)
Forward transform transpose: Real space -> PW basis.
TptrCollection & operator-=(TptrCollection &in, const TptrCollection &other)
Decrement.
Definition: ScalarFieldArray.h:109
TptrCollection operator*(TptrCollection &&in, double scaleFac)
Add (destructible input)
Definition: ScalarFieldArray.h:70
std::vector< ScalarField > ScalarFieldArray
dynamic size collection of real space scalar fields
Definition: ScalarFieldArray.h:32
void randomize(TptrCollection &x)
Initialize to normal random numbers:
Definition: ScalarFieldArray.h:154
Simulation grid descriptor.
Definition: GridInfo.h:45
ScalarFieldTilde J(const ScalarField &, int nThreads=0)
Inverse transform: Real space -> PW basis.
TptrCollection & operator+=(TptrCollection &in, const TptrCollection &other)
Increment.
Definition: ScalarFieldArray.h:107
void initRandom(ScalarField &, double cap=0.0)
initialize element-wise with a unit-normal random number (with a cap if cap>0)
#define TptrCollection
shorthand for templates below (undef&#39;d at end of file)
Definition: ScalarFieldArray.h:34
ScalarField Jdag(const ScalarFieldTilde &, bool compat=false, int nThreads=0)
Inverse transform transpose: PW basis -> real space (preserve input)
double dot(const TptrCollection &x, const TptrCollection &y)
Inner product.
Definition: ScalarFieldArray.h:130
void initZero(TptrCollection &x)
Initialize (non-null) data to zero.
Definition: ScalarFieldArray.h:138
std::shared_ptr< ScalarFieldTildeData > ScalarFieldTilde
A smart reference-counting pointer to ScalarFieldTildeData.
Definition: ScalarField.h:45
TptrCollection & operator*=(TptrCollection &x, double alpha)
Scale.
Definition: ScalarFieldArray.h:60
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.
ScalarField I(const ScalarFieldTilde &, bool compat=false, int nThreads=0)
Forward transform: PW basis -> real space (preserve input)
void nullToZero(TptrCollection &x, const GridInfo &gInfo, int N=0)
Definition: ScalarFieldArray.h:144
void initRandomFlat(TptrCollection &x)
Initialize to random numbers (uniform on 0 to 1)
Definition: ScalarFieldArray.h:150
TptrCollection clone(const TptrCollection &x)
Create a copy of the data (note operator= references same data since Tptr&#39;s are pointers!) ...
Definition: ScalarFieldArray.h:53
void axpy(double alpha, const TptrCollection &x, TptrCollection &y)
y += alpha x
Definition: ScalarFieldArray.h:74
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.
#define die(...)
Quit with an error message (formatted using printf()). Must be called from all processes.
Definition: Util.h:114
std::vector< typename T::DataType * > dataPref(TptrCollection &x)
Extract a std::vector of data pointers from a ScalarFieldArray.
Definition: ScalarFieldArray.h:37
Generic multiplet of data arrays (and specialized to triplets for vector fields in real/reciprocal sp...
TptrCollection operator+(const TptrCollection &in1, const TptrCollection &in2)
Definition: ScalarFieldArray.h:112
std::vector< const typename T::DataType * > constDataPref(const TptrCollection &x)
Extract a std::vector of const data pointers from a const ScalarFieldArray.
Definition: ScalarFieldArray.h:45
std::shared_ptr< ScalarFieldData > ScalarField
A smart reference-counting pointer to ScalarFieldData.
Definition: ScalarField.h:41
TptrCollection operator-(const TptrCollection &in1, const TptrCollection &in2)
Definition: ScalarFieldArray.h:121
std::vector< ScalarFieldTilde > ScalarFieldTildeArray
dynamic size collection of reciprocal space scalar fields
Definition: ScalarFieldArray.h:33
#define assert(expr)
A custom assertion with stack trace (NOTE: enabled in release modes as well)
Definition: Util.h:100