30constexpr double kPi = 3.14159265358979323846;
40 Eigen::Vector3d M = Eigen::Vector3d::Zero();
47 M += site.getCharge() * site.getPos();
48 M += site.getStaticDipole();
49 M += site.getInducedDipole();
56 const Eigen::Vector3d& pos) {
65 m.
q2 += 0.5 * q * pos * pos.transpose();
66 m.
q2 += mu * pos.transpose();
71 const std::vector<const PolarSite*>& exclusions)
const {
81 bool excluded =
false;
82 for (
const PolarSite* skip : exclusions) {
98 const std::vector<std::pair<const PolarSite*, Eigen::Vector3d>>& foreground,
99 const std::vector<const PolarSite*>& background_exclusions,
108 for (
const auto& entry : foreground) {
119 const double bracket =
120 fg.
q0 * bg.
q2.trace() + bg.
q0 * fg.
q2.trace() - fg.
q1.dot(bg.
q1);
121 return -(4.0 * kPi / (3.0 *
volume_)) * bracket;
123 const double bracket =
124 fg.
q0 * bg.
q2(2, 2) + bg.
q0 * fg.
q2(2, 2) - fg.
q1.z() * bg.
q1.z();
125 return -(4.0 * kPi /
volume_) * bracket;
132 const double bracket = fg.
q0 * bg.
q2.trace() - fg.
q1.dot(bg.
q1);
133 return -(4.0 * kPi / (3.0 *
volume_)) * bracket;
135 const double bracket = fg.
q0 * bg.
q2(2, 2) - fg.
q1.z() * bg.
q1.z();
136 return -(4.0 * kPi /
volume_) * bracket;
140 const std::vector<Eigen::Vector3d>& points,
142 const std::vector<const PolarSite*> no_exclusions;
147 Eigen::VectorXd phi(n);
148#pragma omp parallel for schedule(static)
149 for (
Index p = 0; p < n; ++p) {
151 const Eigen::Vector3d& pos = points[std::size_t(p)];
155 fg.
q2 = 0.5 * pos * pos.transpose();
163 const std::vector<const PolarSite*>& exclusions)
const {
171 bool excluded =
false;
172 for (
const PolarSite* skip : exclusions) {
182 const Eigen::Vector3d mu = site.getInducedDipole();
184 m.
q2 += mu * site.getPos().transpose();
191 const std::vector<std::pair<const PolarSite*, Eigen::Vector3d>>& foreground,
192 const std::vector<const PolarSite*>& background_exclusions,
196 for (
const auto& entry : foreground) {
205template <enum Estatic CE>
210 Eigen::Vector3d field;
212 field = -(4.0 * kPi / (3.0 *
volume_)) * M;
214 field = Eigen::Vector3d::Zero();
215 field.z() = -(4.0 * kPi /
volume_) * M.z();
219 target.
V_noE() += field;
EwaldShapeCorrection(double volume, const EwaldRegistry ®istry, EwaldShape shape)
double CalcStaticEnergyBetween(const std::vector< std::pair< const PolarSite *, Eigen::Vector3d > > &foreground, const std::vector< const PolarSite * > &background_exclusions, EwaldChargeState source_state) const
Moments BackgroundMoments(EwaldChargeState source_state, const std::vector< const PolarSite * > &exclusions) const
static void Accumulate(Moments &m, const PolarSite &site, const Eigen::Vector3d &pos)
Eigen::VectorXd PotentialAtMany(const std::vector< Eigen::Vector3d > &points, EwaldChargeState source_state) const
const EwaldRegistry & registry_
double StaticShapeEnergy(const Moments &fg, const Moments &bg) const
double InducedShapeEnergy(const Moments &fg, const Moments &bg) const
Moments BackgroundInducedMoments(EwaldChargeState source_state, const std::vector< const PolarSite * > &exclusions) const
double CalcInducedSourceEnergyBetween(const std::vector< std::pair< const PolarSite *, Eigen::Vector3d > > &foreground, const std::vector< const PolarSite * > &background_exclusions, EwaldChargeState source_state) const
void AddFieldAt(PolarSite &target, EwaldChargeState source_state) const
Eigen::Vector3d TotalDipoleMoment(EwaldChargeState source_state) const
Class to represent Atom/Site in electrostatic+polarization.
const Eigen::Vector3d & V_noE() const
Eigen::Vector3d getStaticDipole() const final
const Eigen::Vector3d & V() const
Charge transport classes.
ClassicalSegment< PolarSite > PolarSegment
Provides a means for comparing floating point numbers.