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 #include <core/ScalarField.h>
21 #include <core/GridInfo.h>
22 #include <core/GpuUtil.h>
23 #include <core/BlasExtra.h>
24 #include <string.h>
25 
26 
27 //------------ class ScalarFieldData ---------------
28 
ScalarFieldData(const GridInfo & gInfo,bool onGpu,PrivateTag)29 ScalarFieldData::ScalarFieldData(const GridInfo& gInfo, bool onGpu, PrivateTag)
30 : FieldData<double>(gInfo, "ScalarField", gInfo.nr, onGpu)
31 {
32 }
clone() const33 ScalarField ScalarFieldData::clone() const
34 {	ScalarField copy(ScalarFieldData::alloc(gInfo, isOnGpu()));
35 	copy->copyData(*this);
36 	return copy;
37 }
alloc(const GridInfo & gInfo,bool onGpu)38 ScalarField ScalarFieldData::alloc(const GridInfo& gInfo, bool onGpu) { return std::make_shared<ScalarFieldData>(gInfo, onGpu, PrivateTag()); }
39 
toMatrix() const40 matrix ScalarFieldData::toMatrix() const
41 {
42   matrix mat = zeroes(gInfo.nr,1);
43   callPref(eblas_daxpy)(gInfo.nr, 1.0, dataPref(), 1, (double*) mat.dataPref(), 2);
44   return mat;
45 }
46 
47 
48 
49 //------------ class ScalarFieldTildeData ---------------
50 
ScalarFieldTildeData(const GridInfo & gInfo,bool onGpu,PrivateTag)51 ScalarFieldTildeData::ScalarFieldTildeData(const GridInfo& gInfo, bool onGpu, PrivateTag)
52 : FieldData<complex>(gInfo, "ScalarFieldTilde", gInfo.nG, onGpu)
53 {
54 }
clone() const55 ScalarFieldTilde ScalarFieldTildeData::clone() const
56 {	ScalarFieldTilde copy(ScalarFieldTildeData::alloc(gInfo, isOnGpu()));
57 	copy->copyData(*this);
58 	return copy;
59 }
alloc(const GridInfo & gInfo,bool onGpu)60 ScalarFieldTilde ScalarFieldTildeData::alloc(const GridInfo& gInfo, bool onGpu) { return std::make_shared<ScalarFieldTildeData>(gInfo, onGpu, PrivateTag()); }
61 
getGzero() const62 double ScalarFieldTildeData::getGzero() const
63 {
64 	#ifdef GPU_ENABLED
65 	if(isOnGpu())
66 	{	double ret;
67 		cudaMemcpy(&ret, dataGpu(false), sizeof(double), cudaMemcpyDeviceToHost);
68 		return ret * scale;
69 	}
70 	#endif
71 	return data(false)[0].real() * scale;
72 }
setGzero(double Gzero)73 void ScalarFieldTildeData::setGzero(double Gzero)
74 {	if(!scale) absorbScale(); //otherwise division by zero below
75 	double scaledGzero = Gzero / scale;
76 	#ifdef GPU_ENABLED
77 	if(isOnGpu())
78 	{	cudaMemcpy(dataGpu(false), &scaledGzero, sizeof(double), cudaMemcpyHostToDevice);
79 		return;
80 	}
81 	#endif
82 	data(false)[0].real() = scaledGzero;
83 }
84 
85 
86 //------------ class complexScalarFieldData ---------------
87 
complexScalarFieldData(const GridInfo & gInfo,bool onGpu,PrivateTag)88 complexScalarFieldData::complexScalarFieldData(const GridInfo& gInfo, bool onGpu, PrivateTag)
89 : FieldData<complex>(gInfo, "complexScalarField", gInfo.nr, onGpu)
90 {
91 }
clone() const92 complexScalarField complexScalarFieldData::clone() const
93 {	complexScalarField copy(complexScalarFieldData::alloc(gInfo, isOnGpu()));
94 	copy->copyData(*this);
95 	return copy;
96 }
alloc(const GridInfo & gInfo,bool onGpu)97 complexScalarField complexScalarFieldData::alloc(const GridInfo& gInfo, bool onGpu) { return std::make_shared<complexScalarFieldData>(gInfo, onGpu, PrivateTag()); }
98 
toMatrix() const99 matrix complexScalarFieldData::toMatrix() const
100 {
101   matrix mat(gInfo.nr,1,isOnGpu());
102   callPref(eblas_copy)(mat.dataPref(), dataPref(), gInfo.nr);
103   return mat;
104 }
105 
106 
107 //------------ class complexScalarFieldTildeData ---------------
108 
complexScalarFieldTildeData(const GridInfo & gInfo,bool onGpu,PrivateTag)109 complexScalarFieldTildeData::complexScalarFieldTildeData(const GridInfo& gInfo, bool onGpu, PrivateTag)
110 : FieldData<complex>(gInfo, "complexScalarFieldTilde", gInfo.nr, onGpu)
111 {
112 }
clone() const113 complexScalarFieldTilde complexScalarFieldTildeData::clone() const
114 {	complexScalarFieldTilde copy(complexScalarFieldTildeData::alloc(gInfo, isOnGpu()));
115 	copy->copyData(*this);
116 	return copy;
117 }
alloc(const GridInfo & gInfo,bool onGpu)118 complexScalarFieldTilde complexScalarFieldTildeData::alloc(const GridInfo& gInfo, bool onGpu) { return std::make_shared<complexScalarFieldTildeData>(gInfo, onGpu, PrivateTag()); }
119 
getGzero() const120 complex complexScalarFieldTildeData::getGzero() const
121 {
122 	#ifdef GPU_ENABLED
123 	if(isOnGpu())
124 	{	complex ret;
125 		cudaMemcpy(&ret, dataGpu(false), sizeof(complex), cudaMemcpyDeviceToHost);
126 		return ret * scale;
127 	}
128 	#endif
129 	return data(false)[0] * scale;
130 }
setGzero(complex Gzero)131 void complexScalarFieldTildeData::setGzero(complex Gzero)
132 {	if(!scale) absorbScale(); //otherwise division by zero below
133 	complex scaledGzero = Gzero * (1./scale);
134 	#ifdef GPU_ENABLED
135 	if(isOnGpu())
136 	{	cudaMemcpy(dataGpu(false), &scaledGzero, sizeof(complex), cudaMemcpyHostToDevice);
137 		return;
138 	}
139 	#endif
140 	data(false)[0] = scaledGzero;
141 }
142 
143 
144 
145 //------------ class RealKernel ---------------
146 
RealKernel(const GridInfo & gInfo)147 RealKernel::RealKernel(const GridInfo& gInfo)
148  : FieldData<double>(gInfo, "RealKernel", gInfo.nG, false) //basically real version of scalarFieldTilde
149 {
150 }
151 
152