2 #include "potentials_base.h" 4 #include "functionparser.h" 6 #include "spherocylinder.h" 7 #include <coulombgalore.h> 22 TPairMatrixPtr sigma_squared;
23 TPairMatrixPtr epsilon_quadruple;
29 const std::string&
name =
"lennardjones",
const std::string&
cite = std::string(),
33 double squared_distance,
const Point& b_towards_a)
const override 35 const auto s6 =
powi((*sigma_squared)(particle_a.
id, particle_b.
id), 3);
36 const auto r6 = squared_distance * squared_distance * squared_distance;
37 const auto r14 = r6 * r6 * squared_distance;
38 return 6.0 * (*epsilon_quadruple)(particle_a.
id, particle_b.
id) * s6 * (2.0 * s6 - r6) /
42 inline double operator()(
const Particle& particle_a,
const Particle& particle_b,
43 double squared_distance,
44 [[maybe_unused]]
const Point& b_towards_a)
const override 46 auto x = (*sigma_squared)(particle_a.
id, particle_b.
id) / squared_distance;
48 return (*epsilon_quadruple)(particle_a.
id, particle_b.
id) * (x * x - x);
84 static constexpr
double two_to_one_sixth_squared = 1.2599210498948732;
96 const std::string&
cite =
"doi:10.1063/1.2895747",
99 inline double operator()(
const Particle& a,
const Particle& b,
double squared_distance,
100 [[maybe_unused]]
const Point& b_towards_a)
const override 102 const auto sigma2 = (*sigma_squared)(a.
id, b.
id);
103 const auto r_min_squared = sigma2 * two_to_one_sixth_squared;
104 auto x = sigma2 / squared_distance;
106 const auto v_lj = (*epsilon_quadruple)(a.
id, b.
id) * (x * x - x);
107 if (squared_distance <= r_min_squared) {
109 return v_lj + (*epsilon)(a.
id, b.
id) * (1.0 - (*lambda)(a.
id, b.
id));
112 return (*lambda)(a.
id, b.
id) * v_lj;
116 const Point& b_towards_a)
const override 118 const auto sigma2 = (*sigma_squared)(a.
id, b.
id);
119 const auto r_min_squared = sigma2 * two_to_one_sixth_squared;
120 const auto s6 = sigma2 * sigma2 * sigma2;
121 const auto r6 = squared_distance * squared_distance * squared_distance;
122 const auto r14 = r6 * r6 * squared_distance;
124 const auto f_lj = 6.0 * (*epsilon_quadruple)(a.
id, b.
id) * s6 * (2.0 * s6 - r6) / r14;
125 if (squared_distance <= r_min_squared) {
127 return f_lj * b_towards_a;
130 return (*lambda)(a.
id, b.
id) * f_lj * b_towards_a;
149 static constexpr
double onefourth = 0.25, twototwosixth = 1.2599210498948732;
151 inline double operator()(
const Particle& a,
const Particle& b,
double squared_distance)
const 153 auto x = (*sigma_squared)(a.
id, b.
id);
154 if (squared_distance > x * twototwosixth) {
157 x = x / squared_distance;
159 return (*epsilon_quadruple)(a.
id, b.
id) * (x * x - x + onefourth);
164 const std::string&
name =
"wca",
const std::string&
cite =
"doi:ct4kh9",
167 inline double operator()(
const Particle& a,
const Particle& b,
double squared_distance,
168 [[maybe_unused]]
const Point& b_towards_a)
const override 170 return operator()(a, b, squared_distance);
174 const Point& b_towards_a)
const override 176 auto x = (*sigma_squared)(a.
id, b.
id);
177 if (squared_distance > x * twototwosixth) {
178 return {0.0, 0.0, 0.0};
180 x = x / squared_distance;
182 return (*epsilon_quadruple)(a.
id, b.
id) * 6.0 * (2.0 * x * x - x) / squared_distance *
196 TPairMatrixPtr sigma_squared;
204 double squared_distance,
const Point&)
const override 206 return squared_distance < (*sigma_squared)(particle_a.
id, particle_b.
id) ? pc::infty : 0.0;
226 TPairMatrixPtr sigma_squared;
227 TPairMatrixPtr epsilon;
232 explicit Hertz(
const std::string&
name =
"hertz");
234 inline double operator()(
const Particle& a,
const Particle& b,
double squared_distance,
235 [[maybe_unused]]
const Point& b_towards_a)
const override 237 if (squared_distance <= (*sigma_squared)(a.
id, b.
id)) {
238 return (*epsilon)(a.
id, b.
id) *
239 pow((1 - (sqrt(squared_distance / (*sigma_squared)(a.
id, b.
id)))), 2.5);
258 TPairMatrixPtr sigma_squared;
259 TPairMatrixPtr epsilon;
267 const Point&)
const override 269 return (squared_distance < (*sigma_squared)(a.
id, b.
id)) ? -(*epsilon)(a.
id, b.
id) : 0.0;
276 double f = 0, s = 0, e = 0;
277 void from_json(
const json& j)
override;
278 void to_json(
json& j)
const override;
285 const Point&)
const override 287 const auto r = sqrt(squared_distance);
288 return f / (r * squared_distance) + e * std::pow(s / r, 12);
319 void from_json(
const json& j)
override;
323 double cutOffSquared()
const;
340 const Point&)
const override 342 if (squared_distance < rc2) {
345 if (squared_distance > rcwc2) {
348 const auto x = std::cos(c * (sqrt(squared_distance) - rc));
353 const Point& b_towards_a)
const override 355 if (squared_distance > rcwc2 || squared_distance < rc2) {
356 return {0.0, 0.0, 0.0};
358 const auto r = sqrt(squared_distance);
359 const auto x1 = std::cos(c * (r - rc));
360 const auto x2 = std::sin(c * (r - rc));
361 return -2.0 * c * eps * x1 * x2 / r * b_towards_a;
364 void to_json(
json& j)
const override;
381 TPairMatrixPtr switching_distance;
382 TPairMatrixPtr switching_width;
383 TPairMatrixPtr epsilon;
390 const std::string&
name =
"cos2",
const std::string&
cite =
"doi:10/chqzjk"s,
393 double cutOffSquared(AtomData::index_type id1, AtomData::index_type id2)
const;
396 const Point& b_towards_a)
const override 398 const auto rc = (*switching_distance)(a.
id, b.
id);
399 const auto wc = (*switching_width)(a.
id, b.
id);
400 const auto cutoff_squared = (rc + wc) * (rc + wc);
401 if (squared_distance > cutoff_squared || squared_distance < (rc * rc)) {
402 return {0.0, 0.0, 0.0};
404 const auto c = pc::pi / (2.0 * wc);
405 const auto r = sqrt(squared_distance);
406 const auto x1 = std::cos(c * (r - rc));
407 const auto x2 = std::sin(c * (r - rc));
408 return -2.0 * c * (*epsilon)(a.
id, b.
id) * x1 * x2 / r * b_towards_a;
411 inline double operator()(
const Particle& a,
const Particle& b,
const double squared_distance,
412 [[maybe_unused]]
const Point& b_towards_a)
const override 414 const auto rc = (*switching_distance)(a.
id, b.
id);
415 if (squared_distance < (rc * rc)) {
416 return -(*epsilon)(a.
id, b.
id);
418 const auto wc = (*switching_width)(a.
id, b.
id);
419 const auto cutoff_squared = (rc + wc) * (rc + wc);
420 if (squared_distance > cutoff_squared) {
423 const auto c = pc::pi / (2.0 * wc);
424 const auto x = std::cos(c * (sqrt(squared_distance) - rc));
425 return -(*epsilon)(a.
id, b.
id) * x * x;
436 double proberadius = 0, conc = 0;
437 void from_json(
const json& j)
override;
439 double area(
double R,
double r,
double center_center_distance_squared)
444 inline double operator()(
const Particle& a,
const Particle& b,
const double squared_distance,
445 [[maybe_unused]]
const Point& b_towards_a)
const override 448 const auto tension = 0.5 * (
atoms[a.
id].tension +
atoms[b.
id].tension);
449 if (fabs(tfe) > 1e-6 or fabs(tension) > 1e-6)
450 return (tension + conc * tfe) *
451 area(0.5 *
atoms[a.
id].sigma, 0.5 *
atoms[b.
id].sigma, squared_distance);
456 const std::string&
cite = std::string());
457 void to_json(
json& j)
const override;
466 void from_json(
const json& j)
override;
469 explicit Coulomb(
const std::string&
name =
"coulomb");
470 double bjerrum_length = 0.0;
473 const Point&)
const override 475 return bjerrum_length * a.
charge * b.
charge / std::sqrt(squared_distance);
478 void to_json(
json& j)
const override;
484 void from_json(
const json& j)
override;
488 const std::string&
cite = std::string());
489 double bjerrum_length{};
492 const Point& b_towards_a)
const override 495 a.
getExt().mulen * b.
getExt().mulen, b_towards_a, 1.0, 0.0);
498 void to_json(
json& j)
const override;
509 std::shared_ptr<PairMatrix<double>> m_neutral, m_charged;
510 void from_json(
const json& j)
override;
514 void to_json(
json& j)
const override;
516 inline double operator()(
const Particle& a,
const Particle& b,
double squared_distance,
517 [[maybe_unused]]
const Point& b_towards_a)
const override 519 double r4inv = 1 / (squared_distance * squared_distance);
521 return (*m_charged)(a.
id, b.
id) * r4inv;
523 return (*m_neutral)(a.
id, b.
id) / squared_distance * r4inv;
527 const Point& b_towards_a)
const override 529 double r6inv = 1 / (squared_distance * squared_distance * squared_distance);
531 return 4 * m_charged->operator()(a.
id, b.
id) * r6inv * b_towards_a;
533 return 6 * m_neutral->operator()(a.
id, b.
id) / squared_distance * r6inv * b_towards_a;
556 void from_json(
const json& j)
override;
559 explicit FENE(
const std::string&
name =
"fene");
560 void to_json(
json& j)
const override;
562 inline double operator()([[maybe_unused]]
const Particle& particle1,
563 [[maybe_unused]]
const Particle& particle2,
double r2,
564 [[maybe_unused]]
const Point& b_towards_a)
const override 566 return (r2 > r02) ? pc::infty : -0.5 * k * r02 * std::log(1 - r2 * r02inv);
570 [[maybe_unused]]
const Particle& particle_b,
double squared_distance,
571 const Point& b_towards_a)
const override 573 return (squared_distance > r02) ? -pc::infty * b_towards_a
574 : -k * r02 / (r02 - squared_distance) * b_towards_a;
584 ::CoulombGalore::Splined pot;
585 virtual void setSelfEnergy();
586 void from_json(
const json& j)
override;
591 inline double operator()(
const Particle& particle_a,
const Particle& particle_b,
592 const double squared_distance,
593 [[maybe_unused]]
const Point& b_towards_a)
const override 595 return bjerrum_length *
596 pot.ion_ion_energy(particle_a.
charge, particle_b.
charge,
597 sqrt(squared_distance) + std::numeric_limits<double>::epsilon());
601 [[maybe_unused]]
double squared_distance,
602 const Point& b_towards_a)
const override 604 return bjerrum_length *
605 pot.ion_ion_force(particle_a.
charge, particle_b.
charge, b_towards_a);
608 void to_json(
json& j)
const override;
609 [[maybe_unused]]
double dielectric_constant(
double M2V);
610 double bjerrum_length;
611 const CoulombGalore::Splined& getCoulombGalore()
const;
621 void setSelfEnergy()
override;
624 explicit Multipole(
const std::string& =
"multipole");
626 inline double operator()(
const Particle& particle_a,
const Particle& particle_b,
627 [[maybe_unused]]
double squared_distance,
628 const Point& b_towards_a)
const override 633 return bjerrum_length * pot.dipole_dipole_energy(mua, mub, b_towards_a);
637 [[maybe_unused]]
double squared_distance,
642 Point ionion = pot.ion_ion_force(particle1.
charge, particle2.
charge, b_towards_a);
643 Point iondip = pot.ion_dipole_force(particle1.
charge, mub, b_towards_a) +
644 pot.ion_dipole_force(particle2.
charge, mua, b_towards_a);
645 Point dipdip = pot.dipole_dipole_force(mua, mub, b_towards_a);
646 return bjerrum_length * (ionion + iondip + dipdip);
666 double charge1 = 0.0;
667 double charge2 = 0.0;
672 std::shared_ptr<Symbols> symbols;
673 double squared_cutoff_distance;
675 void from_json(
const json& j)
override;
677 inline void setSymbols(
const Particle& particle1,
const Particle& particle2,
678 double squared_distance)
const 680 symbols->distance = std::sqrt(squared_distance);
681 symbols->charge1 = particle1.
charge;
682 symbols->charge2 = particle2.
charge;
688 inline double operator()(
const Particle& particle1,
const Particle& particle2,
689 double squared_distance,
690 [[maybe_unused]]
const Point& b_towards_a)
const override 692 if (squared_distance < squared_cutoff_distance) {
693 setSymbols(particle1, particle2, squared_distance);
700 double squared_distance,
const Point& b_towards_b)
const override 702 if (squared_distance < squared_cutoff_distance) {
703 setSymbols(particle_a, particle_b, squared_distance);
704 return -expression.derivative(symbols->distance) / symbols->distance * b_towards_b;
706 return Point::Zero();
710 void to_json(
json& j)
const override;
730 using EnergyFunctor =
731 std::function<double(const Particle&, const Particle&, double, const Point&)>;
732 json backed_up_json_input;
733 bool have_monopole_self_energy =
false;
734 bool have_dipole_self_energy =
false;
736 EnergyFunctor combinePairPotentials(
737 json& potential_array);
742 void from_json(
const json& j)
override;
746 void to_json(
json& j)
const override;
749 const double squared_distance,
750 const Point& b_towards_a = {0, 0, 0})
const override 752 return umatrix(particle_a.
id, particle_b.
id)(particle_a, particle_b, squared_distance,
777 bool hardsphere_repulsion =
false;
778 KnotData() =
default;
779 KnotData(
const base&);
784 bool hardsphere_repulsion =
false;
785 const int max_iterations = 1e6;
786 void streamPairPotential(std::ostream& stream,
const size_t id1,
788 void savePotentials();
789 double findLowerDistance(
int,
int,
double,
double);
790 double findUpperDistance(
int,
int,
double,
double);
792 void createKnots(
int,
int,
double,
794 void from_json(
const json& j)
override;
808 double squared_distance,
809 [[maybe_unused]]
const Point& b_towards_a)
const override 811 const auto& knots = matrix_of_knots(particle_a.
id, particle_b.
id);
812 if (squared_distance >= knots.rmax2) {
815 if (squared_distance > knots.rmin2) {
816 return spline.
eval(knots, squared_distance);
818 if (knots.hardsphere_repulsion) {
TPairMatrixPtr lambda
λ_ij (hydrophobicity parameter)
Definition: potentials.h:90
nlohmann::json json
JSON object.
Definition: json_support.h:10
Eigen::Vector3d Point
3D vector used for positions, velocities, forces etc.
Definition: coordinates.h:7
CombinationRuleType
Known named combination rules for parameters of pair potential interaction.
Definition: potentials_base.h:45
Statically combines two pair potentials at compile-time.
Definition: potentials_base.h:227
double operator()(const Particle &a, const Particle &b, double squared_distance, const Point &) const override
Pair energy between two particles.
Definition: potentials.h:266
constexpr T powi(T x, unsigned int n)
n'th integer power of float
Definition: pow_function.h:14
Multipole interactions.
Definition: potentials.h:618
double operator()(const Particle &a, const Particle &b, double, const Point &b_towards_a) const override
Pair energy between two particles.
Definition: potentials.h:491
Square-well potential.
Definition: potentials.h:253
double operator()(const Particle &, const Particle &, double squared_distance, const Point &) const override
Pair energy between two particles.
Definition: potentials.h:284
ParticleExtension & getExt()
get/create extension
Definition: particle.h:240
Hardsphere potential.
Definition: potentials.h:193
double mu2mu(const Tvec &muA, const Tvec &muB, double muAxmuB, const Tvec &r, double a=1.0, double b=0.0)
Returns dipole-dipole interaction.
Definition: multipole.h:37
Cosine attraction using combination rules (Eq.
Definition: potentials.h:374
Hertz potential.
Definition: potentials.h:221
Arbitrary potentials for specific atom types.
Definition: potentials.h:728
Definition: tabulate.h:28
Set pair potential between cigar-cigar, sphere-sphere, cigar-sphere.
Definition: spherocylinder.h:280
Definition: potentials.h:481
Cosine attraction.
Definition: potentials.h:311
Definition: potentials.h:273
std::function< double(const InteractionData &)> TExtractorFunc
type of a function extracting a potential coefficient from the InteractionData, e.g., sigma or eps
Definition: potentials_base.h:16
std::vector< Faunus::AtomData > atoms
Global instance of atom list.
Definition: atomdata.cpp:242
Custom pair-potential taking math.
Definition: potentials.h:655
Point force(const Particle &a, const Particle &b, const double squared_distance, const Point &b_towards_a) const override
Force on particle a due to particle b.
Definition: potentials.h:173
double operator()(const Particle &a, const Particle &b, const double squared_distance, const Point &) const override
Pair energy between two particles.
Definition: potentials.h:472
void extractorsFromJson(const json &j) override
potential-specific assignment of coefficient extracting functions
Definition: potentials.cpp:691
double operator()(const Particle &particle_a, const Particle &particle_b, double squared_distance, const Point &) const override
Pair energy between two particles.
Definition: potentials.h:203
int id
Particle id/type.
Definition: particle.h:225
Finite Extensible Nonlinear Elastic (FENE) potential.
Definition: potentials.h:551
TPairMatrixPtr epsilon_quadruple
4 * ε_ij
Definition: potentials.h:88
A common ancestor for potentials that use parameter matrices computed from atomic properties and/or c...
Definition: potentials_base.h:198
std::string name
unique name per polymorphic call; used in FunctorPotential::combinePairPotentials ...
Definition: potentials_base.h:138
Particle class for storing positions, id, and other properties.
Definition: particle.h:220
Point force(const Particle &a, const Particle &b, double squared_distance, const Point &b_towards_a) const override
Force on particle a due to particle b.
Definition: potentials.h:395
Point force(const Particle &, const Particle &, double squared_distance, const Point &b_towards_a) const override
Force on particle a due to particle b.
Definition: potentials.h:352
auto distance(T1 first, T2 last)
Distance between two arbitrary contiguous iterators.
Definition: iteratorsupport.h:7
void initPairMatrices() override
potential-specific initialization of parameter matrices
Definition: potentials.cpp:672
Namespace for particle pair-potentials.
Definition: analysis.h:18
double operator()(const Particle &particle_a, const Particle &particle_b, double squared_distance, [[maybe_unused]] const Point &b_towards_a) const override
Policies:
Definition: potentials.h:807
TPairMatrixPtr epsilon
ε_ij.
Definition: potentials.h:89
double charge
Particle charge.
Definition: particle.h:226
double operator()(const Particle &, const Particle &, double squared_distance, const Point &) const override
Definition: potentials.h:339
Lennard-Jones potential with an arbitrary combination rule.
Definition: potentials.h:15
Ashbaugh-Hatch pair potential.
Definition: potentials.h:77
Charge-nonpolar pair interaction.
Definition: potentials.h:505
Base for all pair-potentials.
Definition: potentials_base.h:131
std::string cite
Typically a short-doi litterature reference.
Definition: potentials_base.h:139
Definition: tabulate.h:63
Wrapper for external CoulombGalore library.
Definition: potentials.h:581
Point force(const Particle &a, const Particle &b, double squared_distance, const Point &b_towards_a) const override
Force on particle a due to particle b.
Definition: potentials.h:115
Splined pair potentials.
Definition: potentials.h:770
TPairMatrixPtr sigma_squared
σ_ij²
Definition: potentials.h:87
Point force(const Particle &particle_a, const Particle &particle_b, double squared_distance, const Point &b_towards_b) const override
Force on particle a due to particle b.
Definition: potentials.h:699
T eval(const typename base::data &d, T r2) const
Get tabulated value at f(x)
Definition: tabulate.h:184
Plain Coulomb potential.
Definition: potentials.h:463
Point force(const Particle &a, const Particle &b, double squared_distance, const Point &b_towards_a) const override
Force on particle a due to particle b.
Definition: potentials.h:526
Weeks-Chandler-Andersen pair potential.
Definition: potentials.h:147
double operator()(const Particle &particle_a, const Particle &particle_b, const double squared_distance, const Point &b_towards_a={0, 0, 0}) const override
Pair energy between two particles.
Definition: potentials.h:748
Point force(const Particle &particle_a, const Particle &particle_b, double squared_distance, const Point &b_towards_a) const override
Force on particle a due to particle b.
Definition: potentials.h:32
Pairwise SASA potential calculating the surface area of inter-secting spheres.
Definition: potentials.h:432