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