DFT-EFE
 
Loading...
Searching...
No Matches
SphericalDataNumericalKernels.h
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (c) 2021. *
3 * The Regents of the University of Michigan and DFT-EFE developers. *
4 * *
5 * This file is part of the DFT-EFE code. *
6 * *
7 * DFT-EFE is free software: you can redistribute it and/or modify *
8 * it under the terms of the Lesser GNU General Public License as *
9 * published by the Free Software Foundation, either version 3 of *
10 * the License, or (at your option) any later version. *
11 * *
12 * DFT-EFE is distributed in the hope that it will be useful, but *
13 * WITHOUT ANY WARRANTY; without even the implied warranty *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
15 * See the Lesser GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License at the top level of DFT-EFE distribution. If not, see *
19 * <https://www.gnu.org/licenses/>. *
20 ******************************************************************************/
21
22/*
23 * Inline DFTEFE_HOST_DEVICE_FUNC definitions for
24 * SphericalDataNumerical::Func<memorySpace>.
25 * Included unconditionally by SphericalDataNumerical.h so every translation
26 * unit (CPU or GPU) gets its own inline copy — no cross-TU linkage required.
27 *
28 * @author Avirup Sircar
29 */
30
31#ifndef dftefe_SphericalDataNumericalDeviceKernels_h
32#define dftefe_SphericalDataNumericalDeviceKernels_h
33
37#include <utils/Spline.h>
39#include <cmath>
40
41namespace dftefe
42{
43 namespace atoms
44 {
45 //=========================================================================
46 // SphericalDataNumerical::Func<memorySpace> — default constructor
47 //=========================================================================
48 template <dftefe::utils::MemorySpace memorySpace>
50 : d_radialSpline()
51 , d_l(0)
52 , d_m(0)
53 , d_mEff(0)
54 , d_constant(0.0)
55 , d_cutoff(0.0)
56 , d_smoothness(1.0)
57 , d_polarAngleTolerance(1e-12)
58 , d_cutoffTolerance(1e-12)
59 , d_radiusTolerance(1e-10)
60 {}
61
62 //=========================================================================
63 // SphericalDataNumerical::Func<memorySpace> — full constructor
64 //=========================================================================
65 template <dftefe::utils::MemorySpace memorySpace>
68 int l,
69 int m,
70 int mEff,
71 double constant,
72 double cutoff,
73 double smoothness,
74 double polarAngleTolerance,
75 double cutoffTolerance,
76 double radiusTolerance)
77 : d_radialSpline(radialSpline)
78 , d_l(l)
79 , d_m(m)
80 , d_mEff(mEff)
81 , d_constant(constant)
82 , d_cutoff(cutoff)
83 , d_smoothness(smoothness)
84 , d_polarAngleTolerance(polarAngleTolerance)
85 , d_cutoffTolerance(cutoffTolerance)
86 , d_radiusTolerance(radiusTolerance)
87 {}
88
89 //=========================================================================
90 // SphericalDataNumerical::Func<memorySpace>::getValue
91 //
92 // Single-point evaluation of f(r)*Y_lm(theta,phi)*smoothCutoff(r).
93 // Uses only standard math + Func::eval — callable from both host
94 // and device code.
95 //=========================================================================
96 template <dftefe::utils::MemorySpace memorySpace>
99 const double *point,
100 const double *origin) const
101 {
102 double shifted[3] = {point[0] - origin[0],
103 point[1] - origin[1],
104 point[2] - origin[2]};
105
106 double r, theta, phi;
108 shifted, r, theta, phi, d_polarAngleTolerance);
109
110 if (r > d_cutoff + d_cutoff / d_smoothness)
111 return 0.0;
112
113 const double radialValue = d_radialSpline.eval(r);
114 const double cutoffValue = smoothCutoffValue(r, d_cutoff, d_smoothness);
115 const double plmVal = plm(d_l, d_mEff, cos(theta));
116 const double qm = Qm(d_m, phi);
117
118 return radialValue * cutoffValue * d_constant * plmVal * qm;
119 }
120
121 //=========================================================================
122 // SphericalDataNumerical::Func<memorySpace>::getGradientValue
123 //
124 // Single-point gradient of f(r)*Y_lm(theta,phi)*smoothCutoff(r).
125 // Writes 3 Cartesian components into grad[0..2].
126 //=========================================================================
127 template <dftefe::utils::MemorySpace memorySpace>
130 const double *point,
131 const double *origin,
132 double * grad) const
133 {
134 double shifted[3] = {point[0] - origin[0],
135 point[1] - origin[1],
136 point[2] - origin[2]};
137
138 double r, theta, phi;
140 shifted, r, theta, phi, d_polarAngleTolerance);
141
143 {
144 grad[0] = 0.0;
145 grad[1] = 0.0;
146 grad[2] = 0.0;
147 return;
148 }
149
150 const double cosTheta = cos(theta);
151 const double sinTheta = sin(theta);
152 const double cosPhi = cos(phi);
153 const double sinPhi = sin(phi);
154
155 const double radialValue = d_radialSpline.eval(r);
156 const double radialDeriv = d_radialSpline.deriv(1, r);
157 const double cutoffValue = smoothCutoffValue(r, d_cutoff, d_smoothness);
158 const double cutoffDeriv =
160
161 const double plmVal = plm(d_l, d_mEff, cosTheta);
162 const double dPlmVal = dplmDTheta(d_l, d_mEff, cosTheta);
163 const double qm = Qm(d_m, phi);
164
165 const double Ylm = d_constant * plmVal * qm;
166 const double dYlmDTheta = d_constant * dPlmVal * qm;
167
168 double dYlmDPhiBysinTheta = 0.0;
169 if (d_m != 0)
170 {
171 const double d2PlmVal = d2plmDTheta2(d_l, d_mEff, cosTheta);
172 const double dqm = dQmDPhi(d_m, phi);
173 dYlmDPhiBysinTheta = d_constant *
174 (sinTheta * d2PlmVal + cosTheta * dPlmVal +
175 sinTheta * (double)(d_l * (d_l + 1)) * plmVal) *
176 (1.0 / ((double)d_m * (double)d_m)) * dqm;
177 }
178
179 double dValueDR =
180 (radialDeriv * cutoffValue + cutoffDeriv * radialValue) * Ylm;
181 double dValueDThetaByr = (radialValue / r) * cutoffValue * dYlmDTheta;
182 double dValueDPhiByrsinTheta =
183 (radialValue / r) * cutoffValue * dYlmDPhiBysinTheta;
184
185 if (r < 1e-4 && d_l > 0)
186 {
187 dValueDThetaByr = dValueDR * dYlmDTheta;
188 dValueDPhiByrsinTheta = dValueDR * dYlmDPhiBysinTheta;
189 }
190
191 grad[0] = dValueDR * (sinTheta * cosPhi) +
192 dValueDThetaByr * (cosTheta * cosPhi) -
193 sinPhi * dValueDPhiByrsinTheta;
194 grad[1] = dValueDR * (sinTheta * sinPhi) +
195 dValueDThetaByr * (cosTheta * sinPhi) +
196 cosPhi * dValueDPhiByrsinTheta;
197 grad[2] = dValueDR * cosTheta - dValueDThetaByr * sinTheta;
198 }
199
200 } // namespace atoms
201} // namespace dftefe
202
203#endif // dftefe_SphericalDataNumericalDeviceKernels_h
#define DFTEFE_HOST_DEVICE_FUNC
Definition: DeviceKernelLauncherHelpers.h:306
Func()
Definition: SphericalDataNumericalKernels.h:49
DFTEFE_HOST_DEVICE_FUNC double getValue(const double *point, const double *origin) const
Definition: SphericalDataNumericalKernels.h:98
DFTEFE_HOST_DEVICE_FUNC void getGradientValue(const double *point, const double *origin, double *grad) const
Definition: SphericalDataNumericalKernels.h:129
double d_smoothness
Definition: SphericalDataNumerical.h:209
double d_cutoffTolerance
Definition: SphericalDataNumerical.h:212
double d_radiusTolerance
Definition: SphericalDataNumerical.h:213
double d_cutoff
Definition: SphericalDataNumerical.h:208
double d_polarAngleTolerance
Definition: SphericalDataNumerical.h:211
Definition: Spline.h:54
DFTEFE_HOST_DEVICE_FUNC double smoothCutoffDerivative(const double x, const double r, const double d, const double tolerance)
Definition: SmoothCutoffFunctions.h:33
void convertCartesianToSpherical(const utils::Point &x, double &r, double &theta, double &phi, double polarAngleTolerance)
Definition: SphericalHarmonicFunctions.cpp:251
DFTEFE_HOST_DEVICE_FUNC double smoothCutoffValue(const double x, const double r, const double d)
Definition: SmoothCutoffFunctions.h:23
DFTEFE_HOST_DEVICE_FUNC double dQmDPhi(const int m, const double phi)
Definition: SphericalHarmonicFunctions.h:319
DFTEFE_HOST_DEVICE_FUNC double Qm(const int m, const double phi)
Definition: SphericalHarmonicFunctions.h:306
dealii includes
Definition: AtomFieldDataSpherical.cpp:31