|
35 | 35 |
|
36 | 36 | #include "Config.hpp" |
37 | 37 |
|
38 | | -#include <Eigen/Dense> |
| 38 | +#include <Eigen/Core> |
39 | 39 |
|
40 | 40 | #include "IntegratorHelperFunctions.hpp" |
41 | 41 | #include "Element.hpp" |
42 | 42 | #include "Exception.hpp" |
| 43 | +#include "AlternateSphericalDiffuse.hpp" |
43 | 44 | #include "AnisotropicLiquid.hpp" |
44 | 45 | #include "IonicLiquid.hpp" |
45 | 46 | #include "MetalNP.hpp" |
@@ -214,6 +215,69 @@ struct CollocationIntegrator |
214 | 215 | } |
215 | 216 | /**@}*/ |
216 | 217 |
|
| 218 | + /**@{ Single and double layer potentials for a SphericalDiffuse Green's function with alternative handling of Coulomb singularty by collocation */ |
| 219 | + /*! \tparam ProfilePolicy the permittivity profile for the diffuse interface |
| 220 | + * \param[in] gf Green's function |
| 221 | + * \param[in] e list of finite elements |
| 222 | + */ |
| 223 | + template <typename ProfilePolicy> |
| 224 | + Eigen::MatrixXd singleLayer(const AlternateSphericalDiffuse<CollocationIntegrator, ProfilePolicy> & gf, const std::vector<Element> & e) const { |
| 225 | + // The singular part is "integrated" as usual, while the nonsingular part is evaluated in full |
| 226 | + size_t mat_size = e.size(); |
| 227 | + Eigen::MatrixXd S = Eigen::MatrixXd::Zero(mat_size, mat_size); |
| 228 | + for (size_t i = 0; i < mat_size; ++i) { |
| 229 | + // Fill diagonal |
| 230 | + // Diagonal of S inside the cavity |
| 231 | + double Sii_I = factor_ * std::sqrt(4 * M_PI / e[i].area()); |
| 232 | + double eps_r2 = 0.0; |
| 233 | + std::tie(eps_r2, std::ignore) = gf.epsilon(e[i].center()); |
| 234 | + S(i, i) = Sii_I / eps_r2; |
| 235 | + Eigen::Vector3d source = e[i].center(); |
| 236 | + for (size_t j = 0; j < mat_size; ++j) { |
| 237 | + // Fill off-diagonal |
| 238 | + Eigen::Vector3d probe = e[j].center(); |
| 239 | + if (i != j) S(i, j) = gf.kernelS(source, probe); |
| 240 | + } |
| 241 | + } |
| 242 | + return S; |
| 243 | + } |
| 244 | + /*! \tparam ProfilePolicy the permittivity profile for the diffuse interface |
| 245 | + * \param[in] gf Green's function |
| 246 | + * \param[in] e list of finite elements |
| 247 | + */ |
| 248 | + template <typename ProfilePolicy> |
| 249 | + Eigen::MatrixXd doubleLayer(const AlternateSphericalDiffuse<CollocationIntegrator, ProfilePolicy> & gf, const std::vector<Element> & e) const { |
| 250 | + // The singular part is "integrated" as usual, while the nonsingular part is evaluated in full |
| 251 | + size_t mat_size = e.size(); |
| 252 | + Eigen::MatrixXd D = Eigen::MatrixXd::Zero(mat_size, mat_size); |
| 253 | + for (size_t i = 0; i < mat_size; ++i) { |
| 254 | + // Fill diagonal |
| 255 | + double area = e[i].area(); |
| 256 | + double radius = e[i].sphere().radius(); |
| 257 | + // Diagonal of S inside the cavity |
| 258 | + double Sii_I = factor_ * std::sqrt(4 * M_PI / area); |
| 259 | + // Diagonal of D inside the cavity |
| 260 | + double Dii_I = -factor_ * std::sqrt(M_PI/ area) * (1.0 / radius); |
| 261 | + // "Diagonal" of the directional derivative of the Coulomb singularity separation coefficient |
| 262 | + double invE_grad = gf.inverseEDerivative(e[i].normal(), e[i].center(), e[i].center()); |
| 263 | + |
| 264 | + double eps_r2 = 0.0; |
| 265 | + std::tie(eps_r2, std::ignore) = gf.epsilon(e[i].center()); |
| 266 | + |
| 267 | + D(i, i) = Dii_I + eps_r2 * Sii_I * invE_grad; |
| 268 | + Eigen::Vector3d source = e[i].center(); |
| 269 | + for (size_t j = 0; j < mat_size; ++j) { |
| 270 | + // Fill off-diagonal |
| 271 | + Eigen::Vector3d probe = e[j].center(); |
| 272 | + Eigen::Vector3d probeNormal = e[j].normal(); |
| 273 | + probeNormal.normalize(); |
| 274 | + if (i != j) D(i, j) = gf.kernelD(probeNormal, source, probe); |
| 275 | + } |
| 276 | + } |
| 277 | + return D; |
| 278 | + } |
| 279 | + /**@}*/ |
| 280 | + |
217 | 281 | /**@{ Single and double layer potentials for a MetalNP Green's function by collocation */ |
218 | 282 | template <typename DerivativeTraits> |
219 | 283 | Eigen::MatrixXd singleLayer(const MetalNP<DerivativeTraits, CollocationIntegrator> & /* gf */, const std::vector<Element> & /* e */) const { |
|
0 commit comments