48 "cr_dipole_damping",
"gaussian");
49 if (dd !=
"gaussian" && dd !=
"thole") {
50 throw std::runtime_error(
51 "polarregion: cr_dipole_damping must be gaussian "
57 throw std::runtime_error(
"polarregion: cr_width must be >= 0");
65 [](
const PolarSegment& seg) { return seg.hasChargeResponse(); });
71 if (!seg.hasChargeResponse()) {
82 <<
": " << ncr <<
" of " <<
segments_.size()
83 <<
" segments with charge response, Gaussian width "
86 <<
" dipoles between molecules" << std::flush;
95 double Echange =
E_hist_.getDiff().Etotal();
96 std::string info =
"not converged";
97 bool converged =
false;
98 if (std::abs(Echange) <
deltaE_) {
104 <<
" is " << info <<
" deltaE=" << Echange << std::flush;
112#pragma omp parallel for reduction(+ : e)
129#pragma omp declare reduction(CustomPlus : eeInteractor::E_terms : omp_out += \
136#pragma omp parallel for reduction(CustomPlus : terms)
138 for (
Index j = 0; j < i; ++j) {
143#pragma omp parallel for reduction(CustomPlus : terms)
149#pragma omp parallel for reduction(CustomPlus : terms)
160#pragma omp parallel for reduction(+ : e)
163 e += site.deltaQ_V_ext();
185 Index dof_polarization = 0;
187 dof_polarization += seg.size() * 3;
189 return dof_polarization;
194 Eigen::VectorXd initial_induced_dipoles =
195 Eigen::VectorXd::Zero(dof_polarization);
199 initial_induced_dipoles.segment(index, 3 * seg.size()) =
201 index += 3 * seg.size();
203 return initial_induced_dipoles;
208 Eigen::VectorXd last_induced_dipoles =
209 Eigen::VectorXd::Zero(dof_polarization);
213 last_induced_dipoles.segment<3>(index) = site.Induced_Dipole();
217 return last_induced_dipoles;
224 site.setInduced_Dipole(x.segment<3>(index));
231 const Eigen::VectorXd& initial_guess) {
232 Eigen::VectorXd b = Eigen::VectorXd::Zero(initial_guess.size());
236 auto V = site.V() + site.V_noE();
237 b.segment<3>(index) = -
V;
244 Eigen::DiagonalPreconditioner<double>>
249 Eigen::VectorXd x = cg.solveWithGuess(b, initial_guess);
252 <<
TimeStamp() <<
" CG: #iterations: " << cg.iterations()
253 <<
", estimated error: " << cg.error() << std::flush;
255 if (cg.info() == Eigen::ComputationInfo::NoConvergence) {
257 errormsg_ =
"PCG iterations did not converge";
260 if (cg.info() == Eigen::ComputationInfo::NumericalIssue) {
273 std::accumulate(energies.begin(), energies.end(), 0.0);
275 <<
" Calculated static-static and polar-static "
276 "interaction with other regions"
280 <<
" Calculated static interaction in region "
284 <<
TimeStamp() <<
" Starting Solving for classical polarization with "
285 << dof_polarization <<
" degrees of freedom." << std::flush;
295 <<
" unknowns, CG #iterations: " << info.
iterations
296 <<
", relative residual: " << info.
error << std::flush;
299 errormsg_ =
"charge-response CG iterations did not converge";
310 Eigen::VectorXd initial_induced_dipoles;
325 x = initial_induced_dipoles;
332 <<
" Calculated polar interaction in region"
336 <<
" Calculated polar interaction with other regions"
344 <<
" Internal static energy [hrt]= "
347 <<
" External static energy [hrt]= "
350 << std::setprecision(10)
351 <<
" Total static energy [hrt]= " << e_contrib.
Estatic() << std::flush;
354 <<
" internal dQ-dQ energy [hrt]= "
358 <<
" internal Q-dQ energy [hrt]= "
362 <<
" Internal energy [hrt]= "
366 <<
" External polar energy [hrt]= "
370 << std::setprecision(10)
371 <<
" Total polar energy [hrt]= " << e_contrib.
Epolar() << std::flush;
374 << std::setprecision(10) <<
" Total energy [hrt]= " << e_contrib.
Etotal()
392#pragma omp parallel for reduction(+ : e)
395 double e_thread = 0.0;
415#pragma omp parallel for reduction(+ : e)
417 double e_thread = 0.0;
Induced charges and dipoles of a polar region with charge-response segments (Thole segments may be mi...
double InternalChargeEnergy() const
Info Solve(double tolerance, Index max_iter, bool use_previous)
void addInternalPolarContrib(const eeInteractor::E_terms &induction_terms)
double & E_static_static()
The periodic Ewald background, as a Region.
void ApplyPotentialTo(std::vector< PolarSegment > &foreground) const
double ApplyFieldTo(std::vector< PolarSegment > &foreground) const
Index size() const override
std::vector< PolarSegment > segments_
void WriteToCpt(CheckpointWriter &w) const override
void ReadFromCpt(CheckpointReader &r) override
Eigen::VectorXd CalcInducedDipoleInsideSegments() const
PolarRegion(Index id, Logger &log)
void AppendResult(tools::Property &prop) const override
void WriteInducedDipolesToSegments(const Eigen::VectorXd &x)
double InteractwithEwaldRegion(const EwaldRegion ®ion) override
void SetupChargeResponseSites()
void ReadFromCpt(CheckpointReader &r) override
double InteractwithQMRegion(const QMRegion ®ion) override
void Initialize(const tools::Property &prop) override
bool Converged() const override
eeInteractor::E_terms PolarEnergy() const
Eigen::VectorXd CalcInducedDipolesViaPCG(const Eigen::VectorXd &initial_guess)
bool hasChargeResponse() const
Eigen::VectorXd ReadInducedDipolesFromLastIteration() const
std::string identify() const override
double StaticInteraction()
hist< Energy_terms > E_hist_
void WriteToCpt(CheckpointWriter &w) const override
void LogAndStoreEnergies(Energy_terms e_contrib)
double InteractwithPolarRegion(const PolarRegion ®ion) override
void Evaluate(std::vector< std::unique_ptr< Region > > ®ions) override
double InteractwithStaticRegion(const StaticRegion ®ion) override
double PolarEnergy_extern() const
Class to represent Atom/Site in electrostatic+polarization.
void ApplyQMFieldToPolarSegments(std::vector< PolarSegment > &segments) const
std::vector< double > ApplyInfluenceOfOtherRegions(std::vector< std::unique_ptr< Region > > ®ions)
Timestamp returns the current time as a string Example: cout << TimeStamp().
Mediates interaction between polar and static sites.
double ApplyStaticField(const T &segment1, PolarSegment &segment2) const
double ApplyInducedField(const PolarSegment &segment1, PolarSegment &segment2) const
E_terms CalcPolarEnergy(const S1 &segment1, const S2 &segment2) const
Eigen::VectorXd Cholesky_IntraSegment(const PolarSegment &seg) const
double CalcPolarEnergy_IntraSegment(const PolarSegment &seg) const
#define XTP_LOG(level, log)
void Cite(const std::string &key)
marks a reference as used (thread safe; unknown keys are printed as such)
Charge transport classes.
ClassicalSegment< PolarSite > PolarSegment
ClassicalSegment< StaticSite > StaticSegment
Provides a means for comparing floating point numbers.