Skip to content

Commit 9a9261a

Browse files
committed
Add a SplineFunction class for cubic spline interpolation
1 parent 9afbcef commit 9a9261a

File tree

2 files changed

+94
-27
lines changed

2 files changed

+94
-27
lines changed

src/bin/plot_green_spherical.cpp

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "UniformDielectric.hpp"
1515

1616
std::vector<double> generate_grid(double, double, size_t);
17-
std::string header();
1817
void case1();
1918
void case2();
2019
void case3();
@@ -40,59 +39,48 @@ std::vector<double> generate_grid(double min_val, double max_val, size_t nPoints
4039
return grid;
4140
}
4241

43-
std::string header()
44-
{
45-
std::stringstream tmp;
46-
tmp << "#" << '\t' << "x_2" << '\t' << "z_2" << '\t';
47-
tmp << "gf_value" << '\t' << "image" << '\t' << "Coulomb" << '\t';
48-
tmp << "derivativeProbe" << '\t' << "der_image" << '\t' << "der_Coulomb" << std::endl;
49-
return tmp.str();
50-
}
51-
5242
void case1()
5343
{
54-
size_t nPoints = 100;
44+
size_t nPoints = 200;
5545
double epsInside = 80.0;
5646
double epsOutside = 2.0;
5747
Eigen::Vector3d sphereCenter = Eigen::Vector3d::Zero();
5848
double sphereRadius = 100.0;
59-
double width = 10.0;
49+
double width = 9.0;
6050

61-
Eigen::Vector3d source;
62-
source << 4.0, 0.0, 85.0;
51+
Eigen::Vector3d source = Eigen::Vector3d::Zero();
6352
Eigen::Vector3d probe = Eigen::Vector3d::Zero();
6453

65-
double x_min = 10.0;
66-
double x_max = 300.0;
67-
std::vector<double> x = generate_grid(x_min, x_max, nPoints);
68-
double z_min = 10.0;
69-
double z_max = 300.0;
54+
double z_min = -20.0;
55+
double z_max = 20.0;
7056
std::vector<double> z = generate_grid(z_min, z_max, nPoints);
57+
double delta = 0.1;
7158

7259
std::ofstream out;
7360

7461
SphericalDiffuse<CollocationIntegrator, OneLayerTanh> gf(epsInside, epsOutside, width, sphereRadius, sphereCenter);
7562
LOG(gf);
7663

7764
out.open("gf_spherical_CASE1.dat");
78-
out << header();
7965
out.precision(16);
8066
for (size_t i = 0; i < nPoints; ++i) {
67+
source << 0.0, 0.0, z[i];
8168
for (size_t j = 0; j < nPoints; ++j) {
82-
probe << x[i], 0.0, z[j];
83-
out << '\t' << x[i]
69+
probe << 0.0, 0.0, (z[j] + delta);
70+
out << '\t' << i
71+
<< '\t' << j
72+
<< '\t' << z[i]
8473
<< '\t' << z[j]
85-
<< '\t' << gf.kernelS(source, probe)
86-
<< '\t' << gf.imagePotential(source, probe)
8774
<< '\t' << gf.Coulomb(source, probe)
88-
<< '\t' << gf.derivativeProbe(Eigen::Vector3d::UnitZ(), source, probe)
89-
<< '\t' << gf.CoulombDerivative(Eigen::Vector3d::UnitZ(), source, probe)
90-
<< '\t' << gf.imagePotentialDerivative(Eigen::Vector3d::UnitZ(), source, probe) << std::endl;
75+
<< '\t' << gf.imagePotential(source, probe)
76+
<< '\t' << gf.kernelS(source, probe)
77+
<< '\t' << (1.0 / gf.coefficientCoulomb(source, probe)) << std::endl;
9178
}
9279
}
9380
out.close();
9481
LOG_TIME;
9582

83+
/*
9684
UniformDielectric<AD_directional, CollocationIntegrator> gf_inside(epsInside);
9785
out.open("gf_uniform_inside_CASE1.dat");
9886
out << "#" << '\t' << "x_2" << '\t' << "z_2" << '\t';
@@ -124,4 +112,5 @@ void case1()
124112
}
125113
}
126114
out.close();
115+
*/
127116
}

src/utils/SplineFunction.hpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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+
#ifndef SPLINEFUNCTION_HPP
27+
#define SPLINEFUNCTION_HPP
28+
29+
#include "Config.hpp"
30+
31+
#include <Eigen/Core>
32+
#include <unsupported/Eigen/Splines>
33+
34+
/*! \file SplineFunction.hpp
35+
* \class SplineFunction
36+
* \brief Spline interpolation of a function
37+
* \author Roberto Di Remigio
38+
* \date 2015
39+
*
40+
* Taken from StackOverflow http://stackoverflow.com/a/29825204/2528668
41+
*/
42+
43+
/*! Scale abscissa value to [0, 1] */
44+
inline double scale(double x) {
45+
return (x - xMin_) / (xMax_ - xMin_);
46+
}
47+
48+
/*! Scale abscissa values to [0, 1] */
49+
inline Eigen::RowVectorXd scale(const Eigen::VectorXd & x_vec) {
50+
return x_vec.unaryExpr([](double x) -> double { return scale(x); }).transpose();
51+
}
52+
53+
class SplineFunction
54+
{
55+
private:
56+
typedef Eigen::Spline<double, 1, 3> SplineFit;
57+
public:
58+
/*! \param[in] x vector with abscissa values
59+
* \param[in] y vector with function values
60+
*/
61+
SplineFunction(const Eigen::VectorXd & x, const Eigen::VectorXd & y)
62+
: xMin_(x.minCoeff()), xMax_(x.maxCoeff()),
63+
spline_(Eigen::SplineFitting<SplineFit>::Interpolate(y.transpose(),
64+
std::min<int>(x.rows() - 1, 3), scale(x))
65+
)
66+
{}
67+
/*! \brief Evaluate spline at given point
68+
* \param[in] x evaluation point
69+
*/
70+
double operator()(double x) const {
71+
return spline_(scale(x))(0);
72+
}
73+
private:
74+
double xMin_;
75+
double xMax_;
76+
SplineFit spline_;
77+
};
78+
#endif // SPLINEFUNCTION_HPP

0 commit comments

Comments
 (0)