IMP logo
IMP Reference Guide  develop.634c9b9385,2025/07/20
The Integrative Modeling Platform
LennardJonesTypedPairScore.h
Go to the documentation of this file.
1 /**
2  * \file IMP/atom/LennardJonesTypedPairScore.h
3  * \brief Lennard-Jones score between a pair of particles.
4  *
5  * Copyright 2007-2025 IMP Inventors. All rights reserved.
6  */
7 
8 #ifndef IMPATOM_LENNARD_JONES_TYPED_PAIR_SCORE_H
9 #define IMPATOM_LENNARD_JONES_TYPED_PAIR_SCORE_H
10 
11 #include <IMP/atom/atom_config.h>
12 #include <IMP/generic.h>
13 #include <IMP/PairScore.h>
14 #include <IMP/pair_macros.h>
15 #include <IMP/Pointer.h>
18 
19 IMPATOM_BEGIN_NAMESPACE
20 
21 //! Lennard-Jones score between a pair of particles.
22 /** The two particles in the pair must be LennardJonesTyped particles.
23  The form of the potential is \f[
24  -\epsilon \left[ w_{rep} \left(\frac{r_{min}}{r}\right)^{12}
25  - 2 w_{att} \left(\frac{r_{min}}{r}\right)^{6}\right]
26  \f] where \f$\epsilon\f$ is the depth of the well between the
27  two particles, \f$r_{min}\f$ the distance corresponding to the minimum
28  score, \f$r\f$ the inter-particle distance, and \f$w_{rep}\f$ and
29  \f$w_{att}\f$ the weights on the repulsive and attractive parts of the
30  potential respectively; both weights are 1.0 by default.
31 
32  The well depth is the geometric mean of the individual particles' well
33  depths (as extracted by LennardJonesType::get_well_depth) and the minimum
34  distance the sum of the particles' Lennard-Jones radii (as extracted
35  by LennardJonesType::get_radius; note that this is not necessarily the
36  same as the core::XYZR radius).
37  */
38 template <class SmoothingFuncT>
39 class LennardJonesTypedPairScore final : public PairScore {
40  IMP::PointerMember<SmoothingFuncT> smoothing_function_;
41  double repulsive_weight_, attractive_weight_;
43 
44  double evaluate_index_fast(Model *m,
45  const ParticleIndexPair &p,
47  const int *type_array) const;
48 
49 public:
50  LennardJonesTypedPairScore(SmoothingFuncT *f)
51  : smoothing_function_(f),
52  repulsive_weight_(1.0),
53  attractive_weight_(1.0) {
54  params_ = internal::get_lj_params();
55  }
56 
57  void set_repulsive_weight(double repulsive_weight) {
58  repulsive_weight_ = repulsive_weight;
59  }
60 
61  double get_repulsive_weight() const { return repulsive_weight_; }
62 
63  void set_attractive_weight(double attractive_weight) {
64  attractive_weight_ = attractive_weight;
65  }
66 
67  double get_attractive_weight() const { return attractive_weight_; }
68 
69  virtual double evaluate_index(Model *m,
70  const ParticleIndexPair &p,
71  DerivativeAccumulator *da) const override;
72  virtual ModelObjectsTemp do_get_inputs(
73  Model *m, const ParticleIndexes &pis) const override;
74  virtual bool check_indexes(Model *m,
75  const ParticleIndexes &pis) const override;
77  const int *type_array = LennardJonesTyped::get_type_array(m),
78  evaluate_index_fast(m, p[i], da, type_array) );
80  ;
81 };
82 
83 template <class SmoothingFuncT>
85  Model *m, const ParticleIndexPair &p, DerivativeAccumulator *da) const {
86  LennardJonesTyped lj0(m, std::get<0>(p));
87  LennardJonesTyped lj1(m, std::get<1>(p));
88 
90  double distsqr = delta.get_squared_magnitude();
91  double dist = std::sqrt(distsqr);
92  double dist6 = distsqr * distsqr * distsqr;
93  double dist12 = dist6 * dist6;
94 
95  int index = params_->get_parameter_index(lj0.get_index(), lj1.get_index());
96  double A = params_->aij_[index] * repulsive_weight_;
97  double B = params_->bij_[index] * attractive_weight_;
98  double repulsive = A / dist12;
99  double attractive = B / dist6;
100  double score = repulsive - attractive;
101 
102  if (da) {
103  DerivativePair d = (*smoothing_function_)(
104  score, (6.0 * attractive - 12.0 * repulsive) / dist, dist);
105  algebra::Vector3D deriv = d.second * delta / dist;
106  lj0.add_to_derivatives(deriv, *da);
107  lj1.add_to_derivatives(-deriv, *da);
108  return d.first;
109  } else {
110  return (*smoothing_function_)(score, dist);
111  }
112 }
113 
114 template <class SmoothingFuncT>
116  Model *m, const ParticleIndexes &pis) const {
117  int total = 0;
118  // Every particle should be a LennardJonesTyped particle
119  for (ParticleIndex pi: pis) {
120  LennardJonesTyped lj0(m, pi);
121  // make sure we actually use the object so the compiler doesn't optimize
122  // it out
123  total += lj0.get_index();
124  }
125  return true;
126 }
127 
128 template <class SmoothingFuncT>
131  const int *type_array) const {
132  core::XYZ lj0(m, std::get<0>(p));
133  core::XYZ lj1(m, std::get<1>(p));
134  int type0 = type_array[lj0.get_particle_index().get_index()];
135  int type1 = type_array[lj1.get_particle_index().get_index()];
136 
137  algebra::Vector3D delta = lj0.get_coordinates() - lj1.get_coordinates();
138  double distsqr = delta.get_squared_magnitude();
139  double dist = std::sqrt(distsqr);
140  double dist6 = distsqr * distsqr * distsqr;
141  double dist12 = dist6 * dist6;
142 
143  int index = params_->get_parameter_index(type0, type1);
144  double A = params_->aij_[index] * repulsive_weight_;
145  double B = params_->bij_[index] * attractive_weight_;
146  double repulsive = A / dist12;
147  double attractive = B / dist6;
148  double score = repulsive - attractive;
149 
150  if (da) {
151  DerivativePair d = (*smoothing_function_)(
152  score, (6.0 * attractive - 12.0 * repulsive) / dist, dist);
153  algebra::Vector3D deriv = d.second * delta / dist;
154  lj0.add_to_derivatives(deriv, *da);
155  lj1.add_to_derivatives(-deriv, *da);
156  return d.first;
157  } else {
158  return (*smoothing_function_)(score, dist);
159  }
160 }
161 
162 template <class SmoothingFuncT>
164  Model *m, const ParticleIndexes &pis) const {
165  return IMP::get_particles(m, pis);
166 }
167 
168 IMPATOM_END_NAMESPACE
169 
170 #endif /* IMPATOM_LENNARD_JONES_TYPED_PAIR_SCORE_H */
void add_to_derivatives(const algebra::Vector3D &v, DerivativeAccumulator &d)
Add the vector v to the derivative vector of the x,y,z coordinates.
Definition: XYZ.h:82
Abstract class for scoring object(s) of type ParticleIndexPair.
Definition: PairScore.h:44
Macros for various classes.
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
A decorator for a particle that has a Lennard-Jones potential well.
ParticlesTemp get_particles(Model *m, const ParticleIndexes &ps)
Get the particles from a list of indexes.
A more IMP-like version of the std::vector.
Definition: Vector.h:50
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
Lennard-Jones score between a pair of particles.
Define PairScore.
A decorator for a particle with x,y,z coordinates.
Definition: XYZ.h:30
const algebra::Vector3D & get_coordinates() const
Convert it to a vector.
Definition: XYZ.h:109
std::pair< double, double > DerivativePair
A pair representing a function value with its first derivative.
Definition: types.h:22
Classes to smooth nonbonded interactions.
A nullptr-initialized pointer to an IMP Object.
VectorD< 3 > Vector3D
Definition: VectorD.h:408
double Float
Basic floating-point value (could be float, double...)
Definition: types.h:19
#define IMP_PAIR_SCORE_METHODS_UNCHECKED(Name, Setup, Evaluate)
Definition: pair_macros.h:91
Parameters for a Lennard-Jones interaction.
Class for adding derivatives from restraints to the model.
Compile-time generic restraint and constraint support.