Skip to content

Commit a555520

Browse files
author
Roberto Di Remigio
committed
Get some work done on the Rob-green_spherical branch
1 parent 270fb97 commit a555520

18 files changed

+520
-260
lines changed

src/bi_operators/CollocationIntegrator.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define COLLOCATIONINTEGRATOR_HPP
33

44
#include <iosfwd>
5+
#include <tuple>
56

67
#include "Config.hpp"
78

@@ -54,11 +55,10 @@ struct CollocationIntegrator
5455
double area = e.area();
5556
return (factor_ * std::sqrt(4 * M_PI / area) * epsInv);
5657
}
57-
double computeD(const UniformDielectric<DerivativeTraits, CollocationIntegrator> & gf, const Element & e) const {
58-
double epsInv = 1.0 / gf.epsilon();
58+
double computeD(const UniformDielectric<DerivativeTraits, CollocationIntegrator> & /* gf */, const Element & e) const {
5959
double area = e.area();
6060
double radius = e.sphere().radius();
61-
return (-factor_ * std::sqrt(M_PI/ area) * (1.0 / radius) * epsInv);
61+
return (-factor_ * std::sqrt(M_PI/ area) * (1.0 / radius));
6262
}
6363

6464
double computeS(const IonicLiquid<DerivativeTraits, CollocationIntegrator> & /* gf */, const Element & /* e */) const {
@@ -102,7 +102,10 @@ struct CollocationIntegrator
102102
// "Diagonal" of the directional derivative of the image Green's function
103103
double image_grad = gf.imagePotentialDerivative(e.normal(), e.center(), e.center());
104104

105-
return (Dii_I / coulomb_coeff - Sii_I * coeff_grad + image_grad);
105+
double eps_r2 = 0.0;
106+
std::tie(eps_r2, std::ignore) = gf.epsilon(e.center());
107+
108+
return eps_r2 * (Dii_I / coulomb_coeff - Sii_I * coeff_grad + image_grad);
106109
}
107110

108111
/// Scaling factor for the collocation formulas

src/green/SphericalDiffuse.hpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,13 @@ class SphericalDiffuse : public GreensFunction<Numerical, IntegratorPolicy, Prof
157157
double imagePotential(const Eigen::Vector3d & source, const Eigen::Vector3d & probe) const {
158158
Eigen::Vector3d source_shifted = source - this->origin_;
159159
Eigen::Vector3d probe_shifted = probe - this->origin_;
160-
double r1 = source_shifted.norm();
161-
double r2 = probe_shifted.norm();
162-
double cos_gamma = source_shifted.dot(probe_shifted) / (r1 * r2);
163160

164161
// Obtain coefficient for the separation of the Coulomb singularity
165-
double Cr12 = this->coefficient(r1, r2);
162+
double Cr12 = this->coefficient(source_shifted.norm(), probe_shifted.norm());
166163

167164
double gr12 = 0.0;
168165
for (int L = 0; L <= maxLGreen_; ++L) {
169-
gr12 += this->functionSummation(L, r1, r2, cos_gamma, Cr12);
166+
gr12 += this->functionSummation(L, source_shifted, probe_shifted, Cr12);
170167
}
171168

172169
return gr12;
@@ -217,7 +214,9 @@ class SphericalDiffuse : public GreensFunction<Numerical, IntegratorPolicy, Prof
217214
p2, p1, direction, this->delta_);
218215
}
219216
/*! Handle to the dielectric profile evaluation */
220-
void epsilon(double & v, double & d, double point) const { std::tie(v, d) = this->profile_(point); }
217+
std::tuple<double, double> epsilon(const Eigen::Vector3d & point) const {
218+
return this->profile_((point - this->origin_).norm());
219+
}
221220
EIGEN_MAKE_ALIGNED_OPERATOR_NEW /* See http://eigen.tuxfamily.org/dox/group__TopicStructHavingEigenMembers.html */
222221
private:
223222
using RadialFunction = interfaces::RadialFunction;
@@ -233,18 +232,15 @@ class SphericalDiffuse : public GreensFunction<Numerical, IntegratorPolicy, Prof
233232
Eigen::Map<Eigen::Matrix<double, 3, 1> > p1(sp), p2(pp);
234233
Eigen::Vector3d source = p1 - this->origin_;
235234
Eigen::Vector3d probe = p2 - this->origin_;
236-
double r1 = source.norm();
237-
double r2 = probe.norm();
238-
double r12 = (source - probe).norm();
239-
double cos_gamma = source.dot(probe) / (r1 * r2);
240235

241236
// Obtain coefficient for the separation of the Coulomb singularity
242-
double Cr12 = this->coefficient(r1, r2);
237+
double Cr12 = this->coefficient(source.norm(), probe.norm());
243238

244239
double gr12 = 0.0;
245240
for (int L = 0; L <= maxLGreen_; ++L) {
246-
gr12 += this->functionSummation(L, r1, r2, cos_gamma, Cr12);
241+
gr12 += this->functionSummation(L, source, probe, Cr12);
247242
}
243+
double r12 = (source - probe).norm();
248244

249245
return (1.0 / (Cr12 * r12) + gr12);
250246
}
@@ -335,13 +331,16 @@ class SphericalDiffuse : public GreensFunction<Numerical, IntegratorPolicy, Prof
335331
std::vector<RadialFunction> omega_;
336332
/*! \brief Returns L-th component of the radial part of the Green's function
337333
* \param[in] L angular momentum
338-
* \param[in] r1 first point
339-
* \param[in] r2 second point
340-
* \param[in] cos_gamma cosine of the angle in between first and second point
334+
* \param[in] sp source point, shifted by origin_
335+
* \param[in] pp probe point, shifted by origin_
341336
* \param[in] Cr12 Coulomb singularity separation coefficient
337+
* \note This function expects that the source and probe points have been correctly shifted
338+
* to account for the position of the origin of the dielectric sphere.
342339
*/
343-
double functionSummation(int L, double r1, double r2, double cos_gamma, double Cr12) const {
344-
double gr12 = 0.0;
340+
double functionSummation(int L, const Eigen::Vector3d & sp, const Eigen::Vector3d & pp, double Cr12) const {
341+
double r1 = sp.norm();
342+
double r2 = pp.norm();
343+
double cos_gamma = sp.dot(pp) / (r1 * r2);
345344
// Evaluate Legendre polynomial of order L
346345
// First of all clean-up cos_gamma, Legendre polynomials
347346
// are only defined for -1 <= x <= 1
@@ -369,6 +368,7 @@ class SphericalDiffuse : public GreensFunction<Numerical, IntegratorPolicy, Prof
369368

370369
double denominator = (d_zeta2 - d_omega2) * std::pow(r2, 2) * eps_r2;
371370

371+
double gr12 = 0.0;
372372
if (r1 < r2) {
373373
gr12 = std::exp(zeta1 - zeta2) * (2*L +1) / denominator;
374374
gr12 = (gr12 - std::pow(r1/r2, L) / (r2 * Cr12) ) * pl_x ;

src/solver/PCMSolver.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ class PCMSolver
5454
PCMSolver(IGreensFunction * gfInside, IGreensFunction * gfOutside)
5555
: greenInside_(gfInside), greenOutside_(gfOutside), allocated_(true) {}
5656
virtual ~PCMSolver() {
57-
if (allocated_) {
58-
delete greenInside_;
59-
delete greenOutside_;
60-
}
57+
//if (allocated_) {
58+
// delete greenInside_;
59+
// delete greenOutside_;
60+
//}
6161
}
6262

6363
IGreensFunction * greenInside() const {

tests/bi_operators/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
set(list_of_libraries green cavity pedra utils)
22

3+
34
list(APPEND external_libraries ${ZLIB_LIBRARIES} ${Boost_SYSTEM_LIBRARY} ${Boost_TIMER_LIBRARY} ${Boost_CHRONO_LIBRARY})
5+
add_executable(update_reference_files.x update_reference_files.cpp)
6+
target_link_libraries(update_reference_files.x "${list_of_libraries}" "${external_libraries}")
7+
48
add_boosttest(bi_operators_collocation "${list_of_libraries}" "${external_libraries}")
59
add_reference(vacuum_S_collocation.npy ${CMAKE_CURRENT_BINARY_DIR})
610
add_reference(vacuum_D_collocation.npy ${CMAKE_CURRENT_BINARY_DIR})

tests/bi_operators/bi_operators_collocation.cpp

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,6 @@ BOOST_FIXTURE_TEST_CASE(vacuum, CollocationIntegratorTest)
8181
for (int i = 0; i < cavity.size(); ++i) {
8282
S_results(i) = gf.diagonalS(cavity.elements(i));
8383
}
84-
// In case you need to update the reference files...
85-
/*
86-
unsigned int dim = static_cast<unsigned int>(cavity.size());
87-
const unsigned int shape[] = {dim};
88-
cnpy::npy_save("vacuum_S_collocation.npy", S_results.data(), shape, 1, "w", false);
89-
*/
9084
cnpy::NpyArray raw_S_ref = cnpy::npy_load("vacuum_S_collocation.npy");
9185
int dim_read = raw_S_ref.shape[0];
9286
Eigen::VectorXd S_reference = Eigen::VectorXd::Zero(dim_read);
@@ -104,10 +98,6 @@ BOOST_FIXTURE_TEST_CASE(vacuum, CollocationIntegratorTest)
10498
for (int i = 0; i < cavity.size(); ++i) {
10599
D_results(i) = gf.diagonalD(cavity.elements(i));
106100
}
107-
// In case you need to update the reference files...
108-
/*
109-
cnpy::npy_save("vacuum_D_collocation.npy", D_results.data(), shape, 1, "w", false);
110-
*/
111101
cnpy::NpyArray raw_D_ref = cnpy::npy_load("vacuum_D_collocation.npy");
112102
dim_read = raw_D_ref.shape[0];
113103
Eigen::VectorXd D_reference = Eigen::VectorXd::Zero(dim_read);
@@ -134,12 +124,6 @@ BOOST_FIXTURE_TEST_CASE(uniformdielectric, CollocationIntegratorTest)
134124
for (int i = 0; i < cavity.size(); ++i) {
135125
S_results(i) = gf.diagonalS(cavity.elements(i));
136126
}
137-
// In case you need to update the reference files...
138-
/*
139-
unsigned int dim = static_cast<unsigned int>(cavity.size());
140-
const unsigned int shape[] = {dim};
141-
cnpy::npy_save("uniformdielectric_S_collocation.npy", S_results.data(), shape, 1, "w", false);
142-
*/
143127
cnpy::NpyArray raw_S_ref = cnpy::npy_load("uniformdielectric_S_collocation.npy");
144128
int dim_read = raw_S_ref.shape[0];
145129
Eigen::VectorXd S_reference = Eigen::VectorXd::Zero(dim_read);
@@ -157,10 +141,6 @@ BOOST_FIXTURE_TEST_CASE(uniformdielectric, CollocationIntegratorTest)
157141
for (int i = 0; i < cavity.size(); ++i) {
158142
D_results(i) = gf.diagonalD(cavity.elements(i));
159143
}
160-
// In case you need to update the reference files...
161-
/*
162-
cnpy::npy_save("uniformdielectric_D_collocation.npy", D_results.data(), shape, 1, "w", false);
163-
*/
164144
cnpy::NpyArray raw_D_ref = cnpy::npy_load("uniformdielectric_D_collocation.npy");
165145
dim_read = raw_D_ref.shape[0];
166146
Eigen::VectorXd D_reference = Eigen::VectorXd::Zero(dim_read);
@@ -186,12 +166,6 @@ BOOST_FIXTURE_TEST_CASE(tanhsphericaldiffuse, CollocationIntegratorTest)
186166
for (int i = 0; i < cavity.size(); ++i) {
187167
S_results(i) = gf.diagonalS(cavity.elements(i));
188168
}
189-
// In case you need to update the reference files...
190-
/*
191-
unsigned int dim = static_cast<unsigned int>(cavity.size());
192-
const unsigned int shape[] = {dim};
193-
cnpy::npy_save("tanhsphericaldiffuse_S_collocation.npy", S_results.data(), shape, 1, "w", false);
194-
*/
195169
cnpy::NpyArray raw_S_ref = cnpy::npy_load("tanhsphericaldiffuse_S_collocation.npy");
196170
int dim_read = raw_S_ref.shape[0];
197171
Eigen::VectorXd S_reference = Eigen::VectorXd::Zero(dim_read);
@@ -209,10 +183,6 @@ BOOST_FIXTURE_TEST_CASE(tanhsphericaldiffuse, CollocationIntegratorTest)
209183
for (int i = 0; i < cavity.size(); ++i) {
210184
D_results(i) = gf.diagonalD(cavity.elements(i));
211185
}
212-
// In case you need to update the reference files...
213-
/*
214-
cnpy::npy_save("tanhsphericaldiffuse_D_collocation.npy", D_results.data(), shape, 1, "w", false);
215-
*/
216186
cnpy::NpyArray raw_D_ref = cnpy::npy_load("tanhsphericaldiffuse_D_collocation.npy");
217187
dim_read = raw_D_ref.shape[0];
218188
Eigen::VectorXd D_reference = Eigen::VectorXd::Zero(dim_read);
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/* pcmsolver_copyright_start */
2+
/*
3+
* PCMSolver, an API for the Polarizable Continuum Model
4+
* Copyright (C) 2013 Roberto Di Remigio, Luca Frediani and contributors
5+
*
6+
* This file is part of PCMSolver.
7+
*
8+
* PCMSolver is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Lesser General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* PCMSolver is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public License
19+
* along with PCMSolver. If not, see <http://www.gnu.org/licenses/>.
20+
*
21+
* For information on the complete list of contributors to the
22+
* PCMSolver API, see: <http://pcmsolver.github.io/pcmsolver-doc>
23+
*/
24+
/* pcmsolver_copyright_end */
25+
26+
#include <cmath>
27+
#include <cstdlib>
28+
#include <iostream>
29+
#include <iomanip>
30+
#include <limits>
31+
32+
#include "Config.hpp"
33+
34+
#include <Eigen/Dense>
35+
36+
#include "cnpyPimpl.hpp"
37+
#include "CollocationIntegrator.hpp"
38+
#include "DerivativeTypes.hpp"
39+
#include "Element.hpp"
40+
#include "GePolCavity.hpp"
41+
#include "PhysicalConstants.hpp"
42+
#include "SphericalDiffuse.hpp"
43+
#include "TestingMolecules.hpp"
44+
#include "UniformDielectric.hpp"
45+
#include "Vacuum.hpp"
46+
47+
void save_vacuum();
48+
void save_uniform_dielectric();
49+
void save_tanh_spherical_diffuse();
50+
51+
int main()
52+
{
53+
save_vacuum();
54+
save_uniform_dielectric();
55+
save_tanh_spherical_diffuse();
56+
57+
return EXIT_SUCCESS;
58+
}
59+
60+
void save_vacuum() {
61+
Molecule molec = dummy<0>(1.44 / convertBohrToAngstrom);
62+
double area = 10.0;
63+
GePolCavity cavity(molec, area, 0.0, 100.0);
64+
65+
unsigned int dim = static_cast<unsigned int>(cavity.size());
66+
const unsigned int shape[] = {dim};
67+
68+
Vacuum<AD_directional, CollocationIntegrator<AD_directional, Uniform> > gf;
69+
70+
Eigen::VectorXd S_results = Eigen::VectorXd::Zero(cavity.size());
71+
for (int i = 0; i < cavity.size(); ++i) {
72+
S_results(i) = gf.diagonalS(cavity.elements(i));
73+
}
74+
cnpy::npy_save("vacuum_S_collocation.npy", S_results.data(), shape, 1, "w", false);
75+
76+
Eigen::VectorXd D_results = Eigen::VectorXd::Zero(cavity.size());
77+
for (int i = 0; i < cavity.size(); ++i) {
78+
D_results(i) = gf.diagonalD(cavity.elements(i));
79+
}
80+
cnpy::npy_save("vacuum_D_collocation.npy", D_results.data(), shape, 1, "w", false);
81+
}
82+
83+
void save_uniform_dielectric() {
84+
double epsilon = 80.0;
85+
Molecule molec = dummy<0>(1.44 / convertBohrToAngstrom);
86+
double area = 10.0;
87+
GePolCavity cavity(molec, area, 0.0, 100.0);
88+
89+
unsigned int dim = static_cast<unsigned int>(cavity.size());
90+
const unsigned int shape[] = {dim};
91+
92+
UniformDielectric<AD_directional, CollocationIntegrator<AD_directional, Uniform> > gf(epsilon);
93+
94+
Eigen::VectorXd S_results = Eigen::VectorXd::Zero(cavity.size());
95+
for (int i = 0; i < cavity.size(); ++i) {
96+
S_results(i) = gf.diagonalS(cavity.elements(i));
97+
}
98+
cnpy::npy_save("uniformdielectric_S_collocation.npy", S_results.data(), shape, 1, "w", false);
99+
100+
Eigen::VectorXd D_results = Eigen::VectorXd::Zero(cavity.size());
101+
for (int i = 0; i < cavity.size(); ++i) {
102+
D_results(i) = gf.diagonalD(cavity.elements(i));
103+
}
104+
cnpy::npy_save("uniformdielectric_D_collocation.npy", D_results.data(), shape, 1, "w", false);
105+
}
106+
107+
void save_tanh_spherical_diffuse() {
108+
double epsilon = 80.0;
109+
double width = 5.0;
110+
double sphereRadius = 100.0;
111+
Molecule molec = dummy<0>(1.44 / convertBohrToAngstrom);
112+
double area = 10.0;
113+
GePolCavity cavity(molec, area, 0.0, 100.0);
114+
115+
unsigned int dim = static_cast<unsigned int>(cavity.size());
116+
const unsigned int shape[] = {dim};
117+
118+
SphericalDiffuse<CollocationIntegrator<Numerical, TanhDiffuse>, TanhDiffuse> gf(epsilon, epsilon, width, sphereRadius, Eigen::Vector3d::Zero());
119+
120+
Eigen::VectorXd S_results = Eigen::VectorXd::Zero(cavity.size());
121+
for (int i = 0; i < cavity.size(); ++i) {
122+
S_results(i) = gf.diagonalS(cavity.elements(i));
123+
}
124+
cnpy::npy_save("tanhsphericaldiffuse_S_collocation.npy", S_results.data(), shape, 1, "w", false);
125+
126+
Eigen::VectorXd D_results = Eigen::VectorXd::Zero(cavity.size());
127+
for (int i = 0; i < cavity.size(); ++i) {
128+
D_results(i) = gf.diagonalD(cavity.elements(i));
129+
}
130+
cnpy::npy_save("tanhsphericaldiffuse_D_collocation.npy", D_results.data(), shape, 1, "w", false);
131+
}

0 commit comments

Comments
 (0)