20 #ifndef JDFTX_CORE_VECTORFIELD_H 21 #define JDFTX_CORE_VECTORFIELD_H 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> 41 #define Nloop(code) for(int i=0; i<N; i++) {code} //loop over components (used repeatedly below) 60 Tptr&
operator[](
int i) {
return component[i]; }
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(); }
68 std::vector<typename T::DataType*>
dataGpu();
69 std::vector<const typename T::DataType*>
dataGpu()
const;
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(); }
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(); }
85 explicit operator bool()
const {
bool ret=
true; Nloop(ret = ret && component[i];)
return ret; }
141 template<
class T,
int N>
void axpy(
double alpha,
const Tptr& X,
TptrMul& Y) { Nloop(
axpy(alpha, X, Y[i]);) }
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; }
156 template<
class T,
int N>
double sum(
const TptrMul& X) {
double ret=0.0; Nloop(ret+=
sum(X[i]);)
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]); }
185 template<
int N>
RptrMul I(
const GptrMul& X,
bool compat=
false) {
return I(X.clone(), compat); }
198 template<
int N>
void printStats(
const RptrMul&,
const char* name, FILE* fpLog=stdout);
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(); )
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(); )
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(); )
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(); )
234 template<
class T,
int N>
235 void TptrMul::loadFromFile(
const char* filename)
237 off_t expectedLen = 0;
238 Nloop(expectedLen +=
sizeof(
typename T::DataType) * component[i]->nElem;)
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);
246 FILE* fp = fopen(filename,
"rb");
247 if(!fp)
die(
"Could not open %s for reading.\n", filename)
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)
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)
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);
266 namespace ScalarFieldMultipletPrivate
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)
276 int iStart = (iOpThread*N)/nOpThreads;
277 int iStop = ((iOpThread+1)*N)/nOpThreads;
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);
284 template<
typename FuncOut,
typename FuncIn,
typename Out,
typename In>
285 void threadUnary(FuncOut (*func)(FuncIn,
int),
int N, Out* out, In in)
287 int nOperatorThreads = std::min(nThreadsTot, N);
288 threadLaunch(nOperatorThreads, threadUnary_sub<FuncOut,FuncIn,Out,In>, 0, nThreadsTot, N, func, out, in);
294 {
using namespace ScalarFieldMultipletPrivate;
297 threadUnary<ScalarField,ScalarFieldTilde&&>(func, N, &out, X);
303 {
using namespace ScalarFieldMultipletPrivate;
306 threadUnary(func, N, &out, X);
312 {
using namespace ScalarFieldMultipletPrivate;
315 threadUnary(func, N, &out, X);
321 {
using namespace ScalarFieldMultipletPrivate;
324 threadUnary<ScalarField,ScalarFieldTilde&&>(func, N, &out, X);
328 template<
int N>
void printStats(
const RptrMul& X,
const char* namePrefix, FILE* fpLog)
330 Nloop( sprintf(name,
"%s[%d]", namePrefix, i);
printStats(X[i], name, fpLog); )
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'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'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'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'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's and ScalarFieldTilde'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'd at end of file)
Definition: VectorField.h:37