Skip to content

Commit b8db02b

Browse files
author
Roberto Di Remigio
committed
Merge branch 'Rob-green_spherical' into Rob-green_metalnp
2 parents da1c11b + 89ea5c9 commit b8db02b

9 files changed

+308
-183
lines changed

src/bin/plot_green_spherical.cpp

Lines changed: 161 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,56 @@
77
#include <Eigen/Core>
88

99
#include "CollocationIntegrator.hpp"
10+
#include "DerivativeTypes.hpp"
1011
#include "GeneralPurpose.hpp"
1112
#include "LoggerInterface.hpp"
1213
#include "OneLayerTanh.hpp"
14+
#include "PhysicalConstants.hpp"
1315
#include "SphericalDiffuse.hpp"
1416
#include "UniformDielectric.hpp"
1517

16-
std::vector<double> generate_grid(double, double, size_t);
18+
/*! \brief Generate uniform grid of points in interval
19+
* \param[in] min_val lower bound of interval
20+
* \param[in] max_val upper bound of interval
21+
* \param[in] nPoints number of points in interval
22+
*/
23+
std::vector<double> generate_grid(double min_val, double max_val, size_t nPoints);
24+
25+
/*! \brief Plot Green's function
26+
* The dielectric sphere is centered in (25.0, 25.0, 0.0) with radius 10.0
27+
* and width 5.0 The dielectric profile is parametrized by a tanh sigmoid
28+
* with epsInside = 78.39 (water) and epsOutside = 1.0 (vacuum)
29+
* The maximum value of angular momentum is set to 150
30+
* All distances in Angstrom.
31+
* The source charge is at (26.0, 25.0, 0.0) i.e. inside the dielectric sphere
32+
*/
1733
void case1();
34+
35+
/*! \brief Plot Green's function
36+
* The dielectric sphere is centered in (25.0, 25.0, 0.0) with radius 10.0
37+
* and width 5.0 The dielectric profile is parametrized by a tanh sigmoid
38+
* with epsInside = 78.39 (water) and epsOutside = 1.0 (vacuum)
39+
* The maximum value of angular momentum is set to 150
40+
* All distances in Angstrom.
41+
* The source charge is at (1.0, 1.0, 0.0) i.e. outside the dielectric sphere
42+
*/
1843
void case2();
44+
45+
/*! \brief Plot Green's function
46+
* The dielectric sphere is centered in (25.0, 25.0, 0.0) with radius 10.0
47+
* and width 5.0 The dielectric profile is parametrized by a tanh sigmoid
48+
* with epsInside = 78.39 (water) and epsOutside = 1.0 (vacuum)
49+
* The maximum value of angular momentum is set to 150
50+
* All distances in Angstrom.
51+
* The source charge is at (15.0, 25.0, 0.0) i.e. in the transition layer
52+
*/
1953
void case3();
20-
void case4();
2154

2255
int main()
2356
{
2457
case1();
25-
// case2();
26-
// case3();
27-
// case4();
58+
case2();
59+
case3();
2860

2961
return EXIT_SUCCESS;
3062
}
@@ -42,76 +74,167 @@ std::vector<double> generate_grid(double min_val, double max_val, size_t nPoints
4274
void case1()
4375
{
4476
size_t nPoints = 100;
45-
double epsInside = 80.0;
46-
double epsOutside = 2.0;
77+
double epsInside = 78.39;
78+
double epsOutside = 1.0;
79+
double angToBohr = angstromToBohr(2010);
4780
Eigen::Vector3d sphereCenter = Eigen::Vector3d::Zero();
48-
double sphereRadius = 10.0;
49-
double width = 5.0;
81+
sphereCenter << 25.0, 25.0, 0.0;
82+
sphereCenter *= angToBohr;
83+
double sphereRadius = 10.0 * angToBohr;
84+
double width = 5.0 * angToBohr;
5085
int maxL = 150;
5186

5287
Eigen::Vector3d source = Eigen::Vector3d::Zero();
88+
source << 26.0, 25.0, 0.0;
89+
source *= angToBohr;
5390
Eigen::Vector3d probe = Eigen::Vector3d::Zero();
5491

55-
double min = -50.0;
56-
double max = 50.0;
92+
// Conversion is done later, so that x, y values are printed in Angstrom
93+
double min = 0.0;
94+
double max = 40.0;
5795
std::vector<double> grid = generate_grid(min, max, nPoints);
5896
double delta = 0.1;
5997

6098
std::ofstream out;
6199

62100
SphericalDiffuse<CollocationIntegrator, OneLayerTanh> gf(epsInside, epsOutside, width, sphereRadius, sphereCenter, maxL);
63101
LOG(gf);
102+
gf.toFile("CASE1");
103+
UniformDielectric<AD_directional, CollocationIntegrator> gf_i(epsInside);
104+
UniformDielectric<AD_directional, CollocationIntegrator> gf_o(epsOutside);
64105

65106
out.open("gf_spherical_CASE1.dat");
66107
out.precision(16);
67108
for (size_t i = 0; i < nPoints; ++i) {
68-
source << 1.0, 1.0, 0.0;
69109
for (size_t j = 0; j < nPoints; ++j) {
70-
probe << (grid[i] + delta), (grid[j] + delta), 0.0;
110+
probe << (grid[i] + delta), (grid[j] + delta), delta;
111+
probe *= angToBohr;
71112
out << '\t' << i
72-
<< '\t' << j
73-
<< '\t' << probe(0)
74-
<< '\t' << probe(1)
113+
<< '\t' << j
114+
<< '\t' << grid[i] + delta
115+
<< '\t' << grid[j] + delta
75116
<< '\t' << gf.Coulomb(source, probe)
76117
<< '\t' << gf.imagePotential(source, probe)
77118
<< '\t' << gf.kernelS(source, probe)
78-
<< '\t' << (1.0 / gf.coefficientCoulomb(source, probe)) << std::endl;
119+
<< '\t' << (1.0 / gf.coefficientCoulomb(source, probe))
120+
<< '\t' << gf_i.kernelS(source, probe)
121+
<< '\t' << gf_o.kernelS(source, probe)
122+
<< std::endl;
79123
}
124+
out << std::endl;
80125
}
81126
out.close();
82127
LOG_TIME;
128+
}
83129

84-
/*
85-
UniformDielectric<AD_directional, CollocationIntegrator> gf_inside(epsInside);
86-
out.open("gf_uniform_inside_CASE1.dat");
87-
out << "#" << '\t' << "x_2" << '\t' << "z_2" << '\t';
88-
out << "gf_value" << '\t' << "derivativeProbe" << std::endl;
130+
void case2()
131+
{
132+
size_t nPoints = 100;
133+
double epsInside = 78.39;
134+
double epsOutside = 1.0;
135+
double angToBohr = angstromToBohr(2010);
136+
Eigen::Vector3d sphereCenter = Eigen::Vector3d::Zero();
137+
sphereCenter << 25.0, 25.0, 0.0;
138+
sphereCenter *= angToBohr;
139+
double sphereRadius = 10.0 * angToBohr;
140+
double width = 5.0 * angToBohr;
141+
int maxL = 150;
142+
143+
Eigen::Vector3d source = Eigen::Vector3d::Zero();
144+
source << 1.0, 1.0, 0.0;
145+
source *= angToBohr;
146+
Eigen::Vector3d probe = Eigen::Vector3d::Zero();
147+
148+
// Conversion is done later, so that x, y values are printed in Angstrom
149+
double min = 0.0;
150+
double max = 40.0;
151+
std::vector<double> grid = generate_grid(min, max, nPoints);
152+
double delta = 0.1;
153+
154+
std::ofstream out;
155+
156+
SphericalDiffuse<CollocationIntegrator, OneLayerTanh> gf(epsInside, epsOutside, width, sphereRadius, sphereCenter, maxL);
157+
LOG(gf);
158+
gf.toFile("CASE2");
159+
UniformDielectric<AD_directional, CollocationIntegrator> gf_i(epsInside);
160+
UniformDielectric<AD_directional, CollocationIntegrator> gf_o(epsOutside);
161+
162+
out.open("gf_spherical_CASE2.dat");
163+
out.precision(16);
89164
for (size_t i = 0; i < nPoints; ++i) {
90165
for (size_t j = 0; j < nPoints; ++j) {
91-
probe << x[i], 0.0, z[j];
92-
out << '\t' << x[i]
93-
<< '\t' << z[j]
94-
<< '\t' << gf_inside.kernelS(source, probe)
95-
<< '\t' << gf_inside.derivativeProbe(Eigen::Vector3d::UnitZ(), source, probe) << std::endl;
166+
probe << (grid[i] + delta), (grid[j] + delta), delta;
167+
probe *= angToBohr;
168+
out << '\t' << i
169+
<< '\t' << j
170+
<< '\t' << grid[i] + delta
171+
<< '\t' << grid[j] + delta
172+
<< '\t' << gf.Coulomb(source, probe)
173+
<< '\t' << gf.imagePotential(source, probe)
174+
<< '\t' << gf.kernelS(source, probe)
175+
<< '\t' << (1.0 / gf.coefficientCoulomb(source, probe))
176+
<< '\t' << gf_i.kernelS(source, probe)
177+
<< '\t' << gf_o.kernelS(source, probe)
178+
<< std::endl;
96179
}
180+
out << std::endl;
97181
}
98-
out.precision(16);
99182
out.close();
183+
LOG_TIME;
184+
}
185+
186+
void case3()
187+
{
188+
size_t nPoints = 100;
189+
double epsInside = 78.39;
190+
double epsOutside = 1.0;
191+
double angToBohr = angstromToBohr(2010);
192+
Eigen::Vector3d sphereCenter = Eigen::Vector3d::Zero();
193+
sphereCenter << 25.0, 25.0, 0.0;
194+
sphereCenter *= angToBohr;
195+
double sphereRadius = 10.0 * angToBohr;
196+
double width = 5.0 * angToBohr;
197+
int maxL = 150;
198+
199+
Eigen::Vector3d source = Eigen::Vector3d::Zero();
200+
source << 15.0, 25.0, 0.0;
201+
source *= angToBohr;
202+
Eigen::Vector3d probe = Eigen::Vector3d::Zero();
203+
204+
// Conversion is done later, so that x, y values are printed in Angstrom
205+
double min = 0.0;
206+
double max = 40.0;
207+
std::vector<double> grid = generate_grid(min, max, nPoints);
208+
double delta = 0.1;
209+
210+
std::ofstream out;
211+
212+
SphericalDiffuse<CollocationIntegrator, OneLayerTanh> gf(epsInside, epsOutside, width, sphereRadius, sphereCenter, maxL);
213+
LOG(gf);
214+
gf.toFile("CASE3");
215+
UniformDielectric<AD_directional, CollocationIntegrator> gf_i(epsInside);
216+
UniformDielectric<AD_directional, CollocationIntegrator> gf_o(epsOutside);
100217

101-
UniformDielectric<AD_directional, CollocationIntegrator> gf_outside(epsOutside);
102-
out.open("gf_uniform_outside_CASE1.dat");
103-
out << "#" << '\t' << "x_2" << '\t' << "z_2" << '\t';
104-
out << "gf_value" << '\t' << "derivativeProbe" << std::endl;
218+
out.open("gf_spherical_CASE3.dat");
105219
out.precision(16);
106220
for (size_t i = 0; i < nPoints; ++i) {
107221
for (size_t j = 0; j < nPoints; ++j) {
108-
probe << x[i], 0.0, z[j];
109-
out << '\t' << x[i]
110-
<< '\t' << z[j]
111-
<< '\t' << gf_outside.kernelS(source, probe)
112-
<< '\t' << gf_outside.derivativeProbe(Eigen::Vector3d::UnitZ(), source, probe) << std::endl;
222+
probe << (grid[i] + delta), (grid[j] + delta), delta;
223+
probe *= angToBohr;
224+
out << '\t' << i
225+
<< '\t' << j
226+
<< '\t' << grid[i] + delta
227+
<< '\t' << grid[j] + delta
228+
<< '\t' << gf.Coulomb(source, probe)
229+
<< '\t' << gf.imagePotential(source, probe)
230+
<< '\t' << gf.kernelS(source, probe)
231+
<< '\t' << (1.0 / gf.coefficientCoulomb(source, probe))
232+
<< '\t' << gf_i.kernelS(source, probe)
233+
<< '\t' << gf_o.kernelS(source, probe)
234+
<< std::endl;
113235
}
236+
out << std::endl;
114237
}
115238
out.close();
116-
*/
239+
LOG_TIME;
117240
}

src/green/SphericalDiffuse.hpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,16 @@ class SphericalDiffuse : public GreensFunction<Numerical, IntegratorPolicy, Prof
191191
std::tuple<double, double> epsilon(const Eigen::Vector3d & point) const {
192192
return this->profile_((point + this->origin_).norm());
193193
}
194+
void toFile(const std::string & prefix = "") {
195+
std::string tmp;
196+
prefix.empty() ? tmp = prefix : tmp = prefix + "-";
197+
writeToFile(zetaC_, tmp + "zetaC.dat");
198+
writeToFile(omegaC_, tmp + "omegaC.dat");
199+
for (int L = 1; L <= maxLGreen_; ++L) {
200+
writeToFile(zeta_[L], tmp + "zeta_" + std::to_string(L) + ".dat");
201+
writeToFile(omega_[L], tmp + "omega_" + std::to_string(L) + ".dat");
202+
}
203+
}
194204
EIGEN_MAKE_ALIGNED_OPERATOR_NEW /* See http://eigen.tuxfamily.org/dox/group__TopicStructHavingEigenMembers.html */
195205
private:
196206
using StateType = interfaces::StateType;
@@ -274,14 +284,12 @@ class SphericalDiffuse : public GreensFunction<Numerical, IntegratorPolicy, Prof
274284
LOG("Computing first radial solution L = " + std::to_string(maxLC_));
275285
timerON("computeZeta for coefficient");
276286
zetaC_ = RadialFunction<StateType, LnTransformedRadial, Zeta>(maxLC_, r_0_, r_infinity_, eval_, params_);
277-
writeToFile(zetaC_, "zetaC.dat");
278287
timerOFF("computeZeta for coefficient");
279288
LOG("DONE: Computing first radial solution L = " + std::to_string(maxLC_));
280289

281290
LOG("Computing second radial solution L = " + std::to_string(maxLC_));
282291
timerON("computeOmega for coefficient");
283292
omegaC_ = RadialFunction<StateType, LnTransformedRadial, Omega>(maxLC_, r_0_, r_infinity_, eval_, params_);
284-
writeToFile(omegaC_, "omegaC.dat");
285293
timerOFF("computeOmega for coefficient");
286294
LOG("Computing second radial solution L = " + std::to_string(maxLC_));
287295
LOG("DONE: Computing coefficient for the separation of the Coulomb singularity");
@@ -369,10 +377,14 @@ class SphericalDiffuse : public GreensFunction<Numerical, IntegratorPolicy, Prof
369377
double gr12 = 0.0;
370378
if (r1 < r2) {
371379
gr12 = std::exp(zeta1 - zeta2) * (2*L +1) / denominator;
372-
gr12 = (gr12 - std::pow(r1/r2, L) / (r2 * Cr12) ) * pl_x ;
380+
double f_L = r1 / r2;
381+
for (int i = 1; i < L; ++i) { f_L *= r1 / r2; }
382+
gr12 = (gr12 - f_L / (r2 * Cr12) ) * pl_x ;
373383
} else {
374384
gr12 = std::exp(omega1 - omega2) * (2*L +1) / denominator;
375-
gr12 = (gr12 - std::pow(r2/r1, L) / (r1 * Cr12) ) * pl_x ;
385+
double f_L = r2 / r1;
386+
for (int i = 1; i < L; ++i) { f_L *= r2 / r1; }
387+
gr12 = (gr12 - f_L / (r1 * Cr12) ) * pl_x ;
376388
}
377389

378390
return gr12;
@@ -422,11 +434,15 @@ class SphericalDiffuse : public GreensFunction<Numerical, IntegratorPolicy, Prof
422434
double denominator = (d_zeta2 - d_omega2) * std::pow(r2, 2) * eps_r2;
423435

424436
if (r1 < r2) {
437+
double f_L = r1 / r2;
438+
for (int i = 1; i < maxLC_; ++i) { f_L *= r1 / r2; }
425439
tmp = std::exp(zeta1 - zeta2) * (2*maxLC_ +1) / denominator;
426-
coeff = std::pow(r1/r2, maxLC_) / (tmp * r2);
440+
coeff = f_L / (tmp * r2);
427441
} else {
442+
double f_L = r2 / r1;
443+
for (int i = 1; i < maxLC_; ++i) { f_L *= r2 / r1; }
428444
tmp = std::exp(omega1 - omega2) * (2*maxLC_ +1) / denominator;
429-
coeff = std::pow(r2/r1, maxLC_) / (tmp * r1);
445+
coeff = f_L / (tmp * r1);
430446
}
431447

432448
return coeff;

tests/bi_operators/bi_operators_collocation.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,10 @@
5252
struct CollocationIntegratorTest {
5353
double radius;
5454
double epsilon;
55-
Eigen::Vector3d source, probe, sourceNormal, probeNormal;
5655
GePolCavity cavity;
5756
CollocationIntegratorTest() { SetUp(); }
5857
void SetUp() {
5958
epsilon = 80.0;
60-
source = Eigen::Vector3d::Random();
61-
sourceNormal = source + Eigen::Vector3d::Random();
62-
sourceNormal.normalize();
63-
probe = Eigen::Vector3d::Random();
64-
probeNormal = probe + Eigen::Vector3d::Random();
65-
probeNormal.normalize();
6659

6760
Molecule molec = dummy<0>(1.44 / convertBohrToAngstrom);
6861
double area = 10.0;

tests/bi_operators/bi_operators_numerical.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ struct NumericalIntegratorTest {
5959
Eigen::Vector3d euler;
6060
double eps;
6161
double kappa;
62-
Eigen::Vector3d source, probe, sourceNormal, probeNormal;
6362
GePolCavity cavity;
6463
NumericalIntegratorTest() { SetUp(); }
6564
void SetUp() {
@@ -69,12 +68,6 @@ struct NumericalIntegratorTest {
6968
euler << 0.0, 0.0, 0.0;
7069
eps = 80.0;
7170
kappa = 1.5;
72-
source = Eigen::Vector3d::Random();
73-
sourceNormal = source + Eigen::Vector3d::Random();
74-
sourceNormal.normalize();
75-
probe = Eigen::Vector3d::Random();
76-
probeNormal = probe + Eigen::Vector3d::Random();
77-
probeNormal.normalize();
7871

7972
Molecule molec = dummy<0>(1.44 / convertBohrToAngstrom);
8073
double area = 10.0;
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)