Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Etable.hh
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 //////////////////////////////////////////////////////////////////////
10 /// @begin Etable.hh
11 ///
12 /// @brief
13 /// A class for generating the table for fa_atr/rep and fa_sol
14 ///
15 /// @detailed
16 /// This class is called upon by the ScoringManager. Since actual calculating of the LJ potential
17 /// is time consuming if done multiple times, this class precomputes and discritizes the potential
18 /// (meaning that the potential is broken down into bins). Once the bins have been created, it will
19 /// smooth out the bins, for better interpolation.
20 ///
21 ///
22 /// @authors
23 /// I dont know?
24 /// Steven Combs - comments and skipping of virtual atoms
25 ///
26 /// @last_modified December 6 2010
27 /////////////////////////////////////////////////////////////////////////
28 
29 
30 #ifndef INCLUDED_core_scoring_etable_Etable_hh
31 #define INCLUDED_core_scoring_etable_Etable_hh
32 
33 // Unit Headers
35 
36 // Package Headers
40 
45 
48 #include <utility/pointer/access_ptr.hh>
49 
50 // ObjexxFCL Headers
51 #include <ObjexxFCL/FArray1D.hh>
52 #include <ObjexxFCL/FArray1A.hh>
53 #include <ObjexxFCL/FArray2D.hh>
54 #include <ObjexxFCL/FArray3D.hh>
55 
56 #include <utility/assert.hh>
57 #include <utility/pointer/ReferenceCount.hh>
58 
59 #include <ObjexxFCL/FArray1.fwd.hh>
60 #include <ObjexxFCL/FArray2.fwd.hh>
61 
62 
63 // C++ Headers
64 
65 namespace core {
66 namespace scoring {
67 namespace etable {
68 
69 /// Simple struct for holding the cubic spline polynomials used in
70 /// the etable to interpolate the lennard-jones attractive and
71 /// LK-solvation terms to zero smoothly. These splines have
72 /// exactly two knots to represent them, and the same x values
73 /// are used for all the knots: thus the only parameters needed
74 /// are the y values at the knots, and the second-derivatives
75 /// for the polynomials at knots.
77 {
81  ylo(0.0),
82  yhi(0.0),
83  y2lo(0.0),
84  y2hi(0.0)
85  {}
86 };
87 
88 /// Add in extra repulsion for particular atom pairs, if needed,
89 /// (e.g. for OCbb/OCbb) where the functional form is:
90 /// fa_rep += (xhi - x)^2 * slope
91 /// for values of x between xlo and xhi, and
92 /// fa_rep += (x - xlo ) * extrapolated_slope + ylo
93 /// where extrapolated slope can be anything, but, to defined
94 /// a function with continuous derivatives, should be
95 /// extrapolated_slope = (xhi-xlo)^2*slope
97 {
102  xlo( 0.0 ),
103  xhi( 0.0 ),
104  slope( 0.0 ),
105  extrapolated_slope( 0.0 ),
106  ylo( 0.0 )
107  {}
108 };
109 
111 {
126 
136 
138  maxd2( 0.0 ),
139  hydrogen_interaction( false ),
141  lj_r6_coeff(0.0),
142  lj_r12_coeff(0.0),
143  lj_switch_intercept(0.0),
144  lj_switch_slope(0.0),
145  lj_minimum(0.0),
146  lj_val_at_minimum(0.0),
147  ljatr_spline_xlo(0.0),
148  ljatr_spline_xhi(0.0),
149  ljrep_from_negcrossing(false),
150  lk_coeff1(0.0),
151  lk_coeff2(0.0),
155  ljatr_final_weight(1.0),
156  fasol_final_weight(1.0)
157  {}
158 
159 
160 };
161 
162 
163 /// jk Class definition for Etable
165 
166 public:
167  ///@brief Automatically generated virtual destructor for class deriving directly from ReferenceCount
168  virtual ~Etable();
169 
170  /// constructor
171  Etable(
172  chemical::AtomTypeSetCAP atom_set_in, // like etable namespace
173  EtableOptions const & options,
174  std::string const alternate_parameter_set = ""
175  );
176 
177  Size
178  n_atomtypes() const {
179  return n_atomtypes_;
180  }
181 
182  /// const access to the arrays
183  ObjexxFCL::FArray3D< Real > const &
184  ljatr() const
185  {
186  return ljatr_;
187  }
188 
189  ObjexxFCL::FArray3D< Real > const &
190  ljrep() const
191  {
192  return ljrep_;
193  }
194 
195  ObjexxFCL::FArray3D< Real > const &
196  solv1() const
197  {
198  return solv1_;
199  }
200 
201  ObjexxFCL::FArray3D< Real > const &
202  solv2() const
203  {
204  return solv2_;
205  }
206 
207  /// const access to the deriv arrays
208  ObjexxFCL::FArray3D< Real > const &
209  dljatr() const
210  {
211  return dljatr_;
212  }
213 
214  ObjexxFCL::FArray3D< Real > const &
215  dljrep() const
216  {
217  return dljrep_;
218  }
219 
220  /// @brief return the solvation derivative table for the desolvation of atom1 by atom2
221  ObjexxFCL::FArray3D< Real > const &
222  dsolv1() const
223  {
224  return dsolv1_;
225  }
226 
227  /// @brief return the solvation derivative table that combines atom1 and atom2's desolvations
228  ObjexxFCL::FArray3D< Real > const &
229  dsolv() const
230  {
231  return dsolv_;
232  }
233 
234  Real
235  max_dis() const
236  {
237  return max_dis_;
238  }
239 
240  Real
242  {
243  return safe_max_dis2;
244  }
245 
246  int
248  {
249  return bins_per_A2;
250  }
251 
253  atom_set() const
254  {
255  return atom_set_;
256  }
257 
258  Real
260  {
262  }
263 
264  Real
266  return max_dis_;
267  }
268 
269  Real
272  }
273 
274  Real
277  }
278 
279  ///
280  Real
282  {
283  return nblist_dis2_cutoff_XX_;
284  }
285 
286  ///
287  Real
289  {
290  return nblist_dis2_cutoff_XH_;
291  }
292 
293  ///
294  Real
296  {
297  return nblist_dis2_cutoff_HH_;
298  }
299 
300  /// @brief Returns the maximum lj radius for any non-hydrogen
301  /// atom as defined by the atom-type-set used to create this Etable.
302  Real
304 
305  /// @brief Returns the maximum lj radius for any hydrogen atom as
306  /// defined by the input atom-type-set used to create this Etable.
307  Real
308  max_hydrogen_lj_radius() const;
309 
310  /// set these up in the ctor
311  inline
312  Real
313  lj_radius( int const i ) const
314  {
315  return lj_radius_[i];
316  }
317 
318  ///
319  Real
320  lj_wdepth( int const i ) const
321  {
322  return lj_wdepth_[i];
323  }
324 
325  ///
326  Real
327  lk_dgfree( int const i ) const
328  {
329  return lk_dgfree_[i];
330  }
331 
332  ///
333  Real
334  lk_volume( int const i ) const
335  {
336  return lk_volume_[i];
337  }
338 
339  ///
340  Real
341  lk_lambda( int const i ) const
342  {
343  return lk_lambda_[i];
344  }
345 
346  /// @brief use the analytic_etable_evaluation function, but
347  /// evaluate the function at the old grid points and then interpolate.
348  /// Useful for comparing the original etable evaluation with the
349  /// analytic evaluation.
350  void
352  conformation::Atom const & at1,
353  conformation::Atom const & at2,
354  Real & lj_atrE,
355  Real & lj_repE,
356  Real & fa_solE,
357  Real & d2
358  ) const;
359 
360  /// @brief Use an analytic functional form of the etable to evaluate an atom-pair energy
361  /// without reading from the enormous and uncachable tables.
362  inline
363  void
365  conformation::Atom const & at1,
366  conformation::Atom const & at2,
367  Real & lj_atrE,
368  Real & lj_repE,
369  Real & fa_solE,
370  Real & d2
371  ) const;
372 
373  inline
374  void
376  conformation::Atom const & at1,
377  conformation::Atom const & at2,
378  Real & dljatrE_ddis,
379  Real & dljrepE_ddis,
380  Real & dfasolE_ddis,
381  Real & inv_d
382  ) const;
383 
384  /// @brief Use an analytic functional form of the etable to evaluate an atom-pair energy
385  /// without reading from the enormous and uncachable tables. This version is reserved for
386  /// interactions with hydrogens (hydorgen/hydrogen and hydrogen heavyatom)
387  //void
388  //analytic_etable_evaluation_H(
389  // conformation::Atom const & at1,
390  // conformation::Atom const & at2,
391  // EtableParamsOnePair const & p,
392  // Real const dis2,
393  // Real & lj_atrE,
394  // Real & lj_repE,
395  // Real & fa_solE
396  //) const;
397 
398 private:
399  // initialization routines
400 
403  void calculate_nblist_distance_thresholds( EtableOptions const & options );
404  void
406  chemical::AtomTypeSetCAP atom_set_in,
407  std::string const alternate_parameter_set
408  );
411 
412 
413 private:
414  inline
415  Real
417  Real const dis,
418  EtableParamsOnePair const & p
419  ) const;
420 
421  inline
422  Real
424  Real const dis2,
425  Real const inv_dis2,
426  EtableParamsOnePair const & p
427  ) const;
428 
429  inline
430  Real
432  Real const dis,
433  EtableParamsOnePair const & p
434  ) const;
435 
436  inline
437  Real
439  Real const dis,
440  EtableParamsOnePair const & p
441  ) const;
442 
443 public:
444 
445  static
446  inline
447  Real
448  eval_spline(
449  Real const x,
450  Real const xlo,
451  Real const xhi,
452  SplineParameters const & sp
453  );
454 
455  static
456  inline
457  Real
458  spline_deriv(
459  Real const x,
460  Real const xlo,
461  Real const xhi,
462  SplineParameters const & sp
463  );
464 
465  static
466  inline
467  Real
468  eval_spline(
469  Real const x,
470  Real const xlo,
471  Real const xhi,
472  Real const width,
473  Real const invwidth,
474  SplineParameters const & sp
475  );
476 
477  static
478  inline
479  Real
480  spline_deriv(
481  Real const x,
482  Real const xlo,
483  Real const xhi,
484  Real const width,
485  Real const invwidth,
486  SplineParameters const & sp
487  );
488 
489 private:
490 
491  void
493  ObjexxFCL::FArray3D<Real> & etable,
494  std::string label,
495  std::ostream & out
496  );
497 
498  void
499  input_etable(
500  ObjexxFCL::FArray3D<Real> & etable,
501  const std::string label,
502  std::istream & in
503  );
504 
505  inline
506  EtableParamsOnePair const &
508  Size atype1,
509  Size atype2
510  ) const;
511 
512  inline
515  Size atype1,
516  Size atype2
517  );
518 
519 private:
520 
522 
523  // parameters:
524  int const n_atomtypes_;
525 
526  // from options
527  Real const max_dis_;
528  int const bins_per_A2;
529  Real const Wradius; // global mod to radii
530  Real const lj_switch_dis2sigma; // actual value used for switch
531  Real const max_dis2;
532  int const etable_disbins;
533 
534  // hard-coded for now
537  bool const lj_use_hbond_radii;
543  bool const lj_use_water_radii;
547  Real const min_dis;
548  Real const min_dis2; // was double
551  Real const epsilon;
556  Real nblist_dis2_cutoff_XX_; // for use by the old-style neighborlist
557  Real nblist_dis2_cutoff_XH_; // for use by the old-style neighborlist
558  Real nblist_dis2_cutoff_HH_; // for use by the old-style neighborlist
561 
562  // these three derived from other data
566 
567  ObjexxFCL::FArray2D< Real > lj_sigma_;
568  ObjexxFCL::FArray2D< Real > lj_r6_coeff_;
569  ObjexxFCL::FArray2D< Real > lj_r12_coeff_;
570  ObjexxFCL::FArray2D< Real > lj_switch_intercept_;
571  ObjexxFCL::FArray2D< Real > lj_switch_slope_;
572  ObjexxFCL::FArray1D< Real > lk_inv_lambda2_;
573  ObjexxFCL::FArray2D< Real > lk_coeff_;
574  ObjexxFCL::FArray2D< Real > lk_min_dis2sigma_value_;
575 
576  /// OK: these values reflect the grid point with the lowest energy,
577  /// which could be different from the sum of the lj radii or the lj well depths.
578  /// These vals define the switch point from attractive to repulsive. Repulsive
579  /// interactions start counting at the lj_minima
580  //ObjexxFCL::FArray2D< Real > lj_minima;
581  //ObjexxFCL::FArray2D< Real > lj_vals_at_minima;
582 
583  /// Data needed to describe the splines for the ljatr term
588  //ObjexxFCL::FArray2D< std::pair< Real, Real > > ljatr_spline_xlo_xhi;
589  //ObjexxFCL::FArray2D< SplineParameters > ljatr_spline_parameters;
590 
591  /// Add extra repulsion, if desired, for certain atom pair interactions
592  //ObjexxFCL::FArray2D< ExtraQuadraticRepulsion > ljrep_extra_repulsion;
593 
594  /// Data needed to describe the splines for the fasol term:
595  /// There are two splines needed: one to smooth the transition to where the fasol term goes flat
596  /// as the distance becomes less than the sum of the van der Waals radii (the "close" spline),
597  /// and a second to smooth the transition where the distance goes to the
598  /// fa_max_dis and the energy goes to 0 (the far spline). In between the close
599  /// and far values, the exponential form of the energy function is used.
600  //ObjexxFCL::FArray2D< std::pair< Real, Real > > fasol_spline_close_start_end; // starting and ending points for the lower spline
601  //ObjexxFCL::FArray2D< SplineParameters > fasol_spline_close; // parameters for the lower spline
606  //ObjexxFCL::FArray2D< SplineParameters > fasol_spline_far;
607 
608  /// Should the repulsive component start at ljatr+ljrep = 0 (true) or
609  /// when ljatr reaches its minimum (false )
610  //ObjexxFCL::FArray2D< Size > ljrep_from_negcrossing;
611 
612  /// Data to turn off portions of the interactions between certain atom pairs
613  /// e.g. Hydrogen atoms are repulsive, only, as are the REPLONLY atoms.
614  //ObjexxFCL::FArray2D< Real > ljatr_final_weight;
615  //ObjexxFCL::FArray2D< Real > fasol_final_weight;
616 
617 
618  //
624 
625  // the etables themselves
626  ObjexxFCL::FArray3D< Real > ljatr_;
627  ObjexxFCL::FArray3D< Real > ljrep_;
628  ObjexxFCL::FArray3D< Real > solv1_;
629  ObjexxFCL::FArray3D< Real > solv2_;
630  ObjexxFCL::FArray3D< Real > dljatr_;
631  ObjexxFCL::FArray3D< Real > dljrep_;
632  ObjexxFCL::FArray3D< Real > dsolv_;
633  ObjexxFCL::FArray3D< Real > dsolv1_;
634 
635  utility::vector1< Size > carbon_types; // indices for the standard carbon types
636 
637  // upper-triangle of the n_atomtypes x n_atomtypes table. N^2 - (N*(N-1))/2) entries.
638  // indexed for at1, at2 w/ at1<at2:
639  // ((at1-1)*n_atomtypes + (at2-1) + 1 - (at1*(at1-1)/2)
641 
642  // private methods
643 
644  // get the AtomType object corresponding to a give type index
645  chemical::AtomType const &
646  atom_type( int const type )
647  {
648  return (*atom_set_)[ type ];
649  }
650 
651  //void smooth_etables();
652  //void modify_pot();
653  void make_pairenergy_table();
654 
655  int calculate_normal_disbins() const;
656 
657  void
659  int const normal_disbins,
660  ObjexxFCL::FArray1A< Real > ljatr,
661  ObjexxFCL::FArray1A< Real > dljatr,
662  ObjexxFCL::FArray1A< Real > ljrep,
663  ObjexxFCL::FArray1A< Real > dljrep,
664  ObjexxFCL::FArray1A< Real > fasol1,
665  ObjexxFCL::FArray1A< Real > fasol2,
666  ObjexxFCL::FArray1A< Real > dfasol,
667  ObjexxFCL::FArray1A< Real > dfasol1
668  );
669 
670  void
672  Size atype1,
673  Size atype2,
674  ObjexxFCL::FArray1A< Real > ljatr,
675  ObjexxFCL::FArray1A< Real > dljatr,
676  ObjexxFCL::FArray1A< Real > ljrep,
677  ObjexxFCL::FArray1A< Real > dljrep,
678  ObjexxFCL::FArray1A< Real > fasol1,
679  ObjexxFCL::FArray1A< Real > fasol2,
680  ObjexxFCL::FArray1A< Real > dfasol,
681  ObjexxFCL::FArray1A< Real > dfasol1
682  );
683 
684  void
686  Size atype1,
687  Size atype2,
688  ObjexxFCL::FArray1A< Real > ljatr,
689  ObjexxFCL::FArray1A< Real > dljatr,
690  ObjexxFCL::FArray1A< Real > ljrep,
691  ObjexxFCL::FArray1A< Real > dljrep,
692  ObjexxFCL::FArray1A< Real > fasol1,
693  ObjexxFCL::FArray1A< Real > fasol2,
694  ObjexxFCL::FArray1A< Real > dfasol,
695  ObjexxFCL::FArray1A< Real > dfasol1
696  );
697 
698  void
700  Size atype1,
701  Size atype2,
702  ObjexxFCL::FArray1A< Real > ljatr,
703  ObjexxFCL::FArray1A< Real > dljatr,
704  ObjexxFCL::FArray1A< Real > ljrep,
705  ObjexxFCL::FArray1A< Real > dljrep,
706  ObjexxFCL::FArray1A< Real > fasol1,
707  ObjexxFCL::FArray1A< Real > fasol2,
708  ObjexxFCL::FArray1A< Real > dfasol,
709  ObjexxFCL::FArray1A< Real > dfasol1
710  );
711 
712  void
714  Size atype1,
715  Size atype2,
716  ObjexxFCL::FArray1A< Real > ljrep,
717  ObjexxFCL::FArray1A< Real > ljatr,
718  ObjexxFCL::FArray1A< Real > dljatr,
719  ObjexxFCL::FArray1A< Real > fasol1,
720  ObjexxFCL::FArray1A< Real > fasol2,
721  ObjexxFCL::FArray1A< Real > dfasol,
722  ObjexxFCL::FArray1A< Real > dfasol1
723  );
724 
725  // helper functions
726  void
728  ObjexxFCL::FArray2< Real > & lj_sigma,
729  ObjexxFCL::FArray2< Real > & lj_r6_coeff,
730  ObjexxFCL::FArray2< Real > & lj_r12_coeff,
731  ObjexxFCL::FArray2< Real > & lj_switch_intercept,
732  ObjexxFCL::FArray2< Real > & lj_switch_slope,
733  ObjexxFCL::FArray1< Real > & lk_inv_lambda2,
734  ObjexxFCL::FArray2< Real > & lk_coeff,
735  ObjexxFCL::FArray2< Real > & lk_min_dis2sigma_value
736  );
737 
738  void
740  Real dis2,
741  int & atype1,
742  int & atype2,
743  Real & atrE,
744  Real & d_atrE,
745  Real & repE,
746  Real & d_repE,
747  Real & solvE1,
748  Real & solvE2,
749  Real & dsolvE1,
750  Real & dsolvE2,
751  ObjexxFCL::FArray2< Real > & lj_sigma,
752  ObjexxFCL::FArray2< Real > & lj_r6_coeff,
753  ObjexxFCL::FArray2< Real > & lj_r12_coeff,
754  ObjexxFCL::FArray2< Real > & lj_switch_intercept,
755  ObjexxFCL::FArray2< Real > & lj_switch_slope,
756  ObjexxFCL::FArray1< Real > & lk_inv_lambda2,
757  ObjexxFCL::FArray2< Real > & lk_coeff,
758  ObjexxFCL::FArray2< Real > & lk_min_dis2sigma_value
759  );
760 
761  //void
762  //zero_hydrogen_and_water_ljatr();
763 
764 };
765 
766 //////////////////// Inline Etable Evaluators /////////////////
767 inline
768 void
770  conformation::Atom const & at1,
771  conformation::Atom const & at2,
772  Real & lj_atrE,
773  Real & lj_repE,
774  Real & fa_solE,
775  Real & dis2
776 ) const
777 {
778  using namespace core;
779  using namespace core::scoring::etable;
780  dis2 = at1.xyz().distance_squared( at2.xyz() );
781 
782  int atype1 = at1.type() < at2.type() ? at1.type() : at2.type();
783  int atype2 = at1.type() < at2.type() ? at2.type() : at1.type();
784  lj_atrE = 0; lj_repE = 0; fa_solE = 0;
785 
786  // locals
787  Real ljE;
788 
789  Real atrE = 0.;
790  Real repE = 0.;
791 
792  // ctsa - epsilon allows final bin value to be calculated
793  if ( dis2 > max_dis2 + epsilon ) return;
794 
795  EtableParamsOnePair const & p = analytic_params_for_pair( atype1, atype2 );
796  if ( dis2 < min_dis2 ) dis2 = min_dis2;
797 
798  if ( dis2 > p.maxd2 ) return;
799 
800  //if ( p.hydrogen_interaction ) {
801  // analytic_etable_evaluation_H(
802  // at1, at2, p, dis2, lj_atrE, lj_repE, fa_solE );
803  // return;
804  //}
805 
806  Real const dis = std::sqrt(dis2);
807  Real const inv_dis = 1.0/dis;
808  Real const inv_dis2 = inv_dis * inv_dis;
809 
810  if ( dis2 < p.ljrep_linear_ramp_d2_cutoff ) { // dis * p.inv_lj_sigma < lj_switch_dis2sigma ) {
811  // ctsa - use linear ramp instead of lj when the dis/sigma ratio drops below theshold
812  ljE = analytic_ljrep_linearized( dis, p );
813  } else if ( dis < p.ljatr_spline_xlo ) {
814  // ctsa - calc regular lennard-jones
815  ljE = analytic_lj_generic_form( dis2, inv_dis2, p ); // p.lj_r12_coeff * inv_dis12 + p.lj_r6_coeff * inv_dis6;
816  } else if ( dis < p.ljatr_spline_xhi ) {
817  ljE = analytic_ljatr_spline_ramp_to_zero( dis, p );
818  } else {
819  /// assuming ljatr_spline_xhi == LK distance cutoff, since this will skip lk evaluation
820  return;
821  }
822 
823  /// Divvy up the lennard-jones energies into attractive and repulsive components;
824  /// for most atom pairs, the attractive component goes smoothly to a constant,
825  /// as the atoms approach, and then the repulsive component takes over from there.
826  if ( p.ljrep_from_negcrossing ) {
827  // only for the REPLS and HREPS atom types: start repelling when the lennard-jones term
828  // goes from being attractive to repulsive.
829  if (ljE < 0 ) atrE = ljE;
830  else repE = ljE;
831  } else if ( dis < p.lj_minimum ) {
832  atrE = p.lj_val_at_minimum;
833  repE = ljE - p.lj_val_at_minimum;
834  } else {
835  atrE = ljE;
836  }
837 
838  /// Some atom pairs include extra repulsion that's modeled as a quadratic function
839  /// in some region and then linearized outside of that region. Specifically, this code
840  /// exists for the OCbb / Ocbb interactions.
841  ExtraQuadraticRepulsion const & exrep = p.ljrep_extra_repulsion;
842  if ( dis < exrep.xhi ) {
843  if ( dis < exrep.xlo ) {
844  repE += ( dis - exrep.xlo ) * exrep.extrapolated_slope + exrep.ylo;
845  } else {
846  repE += ( exrep.xhi - dis ) * ( exrep.xhi - dis ) * exrep.slope;
847  }
848  }
849 
850  /// Now zero out the attractive energy if necessry; this is done for hydrogen interactions
851  lj_atrE = atrE * p.ljatr_final_weight;
852  lj_repE = repE;
853 
854  /// Now handle solvation.
855  /// a) At distances below p.fasol_spline_close_start, the value of fasol is held constant.
856  /// b) Then there's a spline to smooth between this constant region and the exponential region.
857  /// c) Then the exponential region.
858  /// d) Then the spline to smooth between the exponential region and where the energy goes to zero.
859  if ( dis < p.fasol_spline_close_start ) {
860  fa_solE = p.fasol_spline_close.ylo * p.fasol_final_weight;
861  } else if ( dis < p.fasol_spline_close_end ) {
862  fa_solE = eval_spline( dis, p.fasol_spline_close_start, p.fasol_spline_close_end, p.fasol_spline_close );
863  fa_solE *= p.fasol_final_weight;
864  //Real const fasol_spline_knots_diff = p.fasol_spline_close_end - p.fasol_spline_close_start;
865  //Real const fasol_spline_knots_diff_inv = 1/fasol_spline_knots_diff;
866  //Real const a = ( p.fasol_spline_close_end - dis ) * fasol_spline_knots_diff_inv;
867  //Real const b = ( dis - p.fasol_spline_close_start ) * fasol_spline_knots_diff_inv;
868  //SplineParameters const & sp = p.fasol_spline_close;
869  //fa_solE = a*sp.ylo + b*sp.yhi + ((a*a*a-a)*sp.y2lo + (b*b*b-b)*sp.y2hi)*fasol_spline_knots_diff*fasol_spline_knots_diff / 6;
870  } else if ( dis < fasol_spline_far_xlo ) {
871  /// exponential evaluation
872  /// assert( atype1 <= atype2 ), which is accomplished at the top of this function.
873  Real const dis_rad1 = dis - lj_radius(atype1);
874  Real const x1 = ( dis_rad1 * dis_rad1 ) * lk_inv_lambda2_(atype1);
875  Real const dis_rad2 = dis - lj_radius(atype2);
876  Real const x2 = ( dis_rad2 * dis_rad2 ) * lk_inv_lambda2_(atype2);
877 
878  fa_solE = inv_dis2 * ( std::exp(-x1) * p.lk_coeff1 + std::exp(-x2) * p.lk_coeff2 );
879  fa_solE *= p.fasol_final_weight;
880 
881  } else if ( dis < fasol_spline_far_xhi ) {
882  fa_solE = eval_spline( dis,
885  p.fasol_spline_far );
886  //Real const a = ( fasol_spline_far_xhi - dis ) * fasol_spline_far_diff_xhi_xlo_inv;
887  //Real const b = ( dis - fasol_spline_far_xlo ) * fasol_spline_far_diff_xhi_xlo_inv;
888  //SplineParameters const & sp = p.fasol_spline_far;
889  //
890  //fa_solE = a*sp.ylo + b*sp.yhi + ((a*a*a-a)*sp.y2lo + (b*b*b-b)*sp.y2hi)*fasol_spline_far_diff_xhi_xlo*fasol_spline_far_diff_xhi_xlo / 6;
891  fa_solE *= p.fasol_final_weight;
892  } else {
893  fa_solE = 0;
894  }
895 }
896 
897 inline
898 void
900  conformation::Atom const & at1,
901  conformation::Atom const & at2,
902  Real & dljatrE_ddis,
903  Real & dljrepE_ddis,
904  Real & dfasolE_ddis,
905  Real & inv_d
906 ) const
907 {
908  using namespace core;
909  using namespace core::scoring::etable;
910  Real dis2 = at1.xyz().distance_squared( at2.xyz() );
911 
912  int atype1 = at1.type() < at2.type() ? at1.type() : at2.type();
913  int atype2 = at1.type() < at2.type() ? at2.type() : at1.type();
914  dljatrE_ddis = dljrepE_ddis = dfasolE_ddis = 0.0; inv_d = 1;
915 
916  // locals
917  Real dljE(1), inv_dis6(1);
918 
919  // ctsa - epsilon allows final bin value to be calculated
920  if ( dis2 > max_dis2 + epsilon ) return;
921 
922  EtableParamsOnePair const & p = analytic_params_for_pair( atype1, atype2 );
923  if ( dis2 < min_dis2 ) dis2 = min_dis2;
924 
925  if ( dis2 > p.maxd2 ) return;
926 
927  //if ( p.hydrogen_interaction ) {
928  // analytic_etable_evaluation_H(
929  // at1, at2, p, dis2, lj_atrE, lj_repE, fa_solE );
930  // return;
931  //}
932 
933  Real const dis = std::sqrt(dis2);
934  Real const inv_dis = 1.0/dis; inv_d = inv_dis;
935  Real const inv_dis2 = inv_dis * inv_dis;
936 
937  if ( dis2 < p.ljrep_linear_ramp_d2_cutoff ) { // dis * p.inv_lj_sigma < lj_switch_dis2sigma ) {
938  // ctsa - use linear ramp instead of lj when the dis/sigma ratio drops below theshold
939  dljE = p.lj_switch_slope;
940  } else if ( dis < p.ljatr_spline_xlo ) {
941  // ctsa - calc regular lennard-jones
942  inv_dis6 = inv_dis2 * inv_dis2 * inv_dis2;
943  Real const inv_dis7 = inv_dis * inv_dis6;
944 
945  dljE = inv_dis7 * ( -12.*p.lj_r12_coeff * inv_dis6 - 6.* p.lj_r6_coeff );
946  } else if ( dis < p.ljatr_spline_xhi ) {
948  } else {
949  /// assuming ljatr_spline_xhi == LK distance cutoff, since this will skip lk evaluation
950  return;
951  }
952 
953  /// Divvy up the lennard-jones energies into attractive and repulsive components;
954  /// for most atom pairs, the attractive component goes smoothly to a constant,
955  /// as the atoms approach, and then the repulsive component takes over from there.
956  if ( p.ljrep_from_negcrossing ) {
957  // only for the REPLS and HREPS atom types: start repelling when the lennard-jones term
958  // goes from being attractive to repulsive.
959  // so, calculate the energy to decide whether it's attractive or repulsive
960  if ( dis2 < p.ljrep_linear_ramp_d2_cutoff || inv_dis6*( p.lj_r12_coeff*inv_dis6 + p.lj_r6_coeff ) > 0.0 ) {
961  dljrepE_ddis = dljE;
962  }
963  } else if ( dis < p.lj_minimum ) {
964  dljatrE_ddis = 0;
965  dljrepE_ddis = dljE;
966  } else {
967  dljatrE_ddis = dljE;
968  }
969 
970  /// Some atom pairs include extra repulsion that's modeled as a quadratic function
971  /// in some region and then linearized outside of that region. Specifically, this code
972  /// exists for the OCbb / Ocbb interactions.
973  ExtraQuadraticRepulsion const & exrep = p.ljrep_extra_repulsion;
974  if ( dis < exrep.xhi ) {
975  if ( dis < exrep.xlo ) {
976  dljrepE_ddis += exrep.extrapolated_slope;
977  } else {
978  dljrepE_ddis += -2 * ( exrep.xhi - dis ) * exrep.slope;
979  }
980  }
981  /// Finally, zero out the attractive energy derivatives if necessry; this is done for hydrogen interactions
982  dljatrE_ddis *= p.ljatr_final_weight;
983 
984  /// Now handle solvation.
985  /// a) At distances below p.fasol_spline_close_start, the value of fasol is held constant.
986  /// b) Then there's a spline to smooth between this constant region and the exponential region.
987  /// c) Then the exponential region.
988  /// d) Then the spline to smooth between the exponential region and where the energy goes to zero.
989  if ( dis < p.fasol_spline_close_start ) {
990  dfasolE_ddis = 0;
991  } else if ( dis < p.fasol_spline_close_end ) {
992  dfasolE_ddis = spline_deriv( dis, p.fasol_spline_close_start, p.fasol_spline_close_end, p.fasol_spline_close );
993  dfasolE_ddis *= p.fasol_final_weight;
994  //Real const fasol_spline_knots_diff = p.fasol_spline_close_end - p.fasol_spline_close_start;
995  //Real const fasol_spline_knots_diff_inv = 1/fasol_spline_knots_diff;
996  //Real const a = ( p.fasol_spline_close_end - dis ) * fasol_spline_knots_diff_inv;
997  //Real const b = ( dis - p.fasol_spline_close_start ) * fasol_spline_knots_diff_inv;
998  //SplineParameters const & sp = p.fasol_spline_close;
999  //fa_solE = a*sp.ylo + b*sp.yhi + ((a*a*a-a)*sp.y2lo + (b*b*b-b)*sp.y2hi)*fasol_spline_knots_diff*fasol_spline_knots_diff / 6;
1000  } else if ( dis < fasol_spline_far_xlo ) {
1001  /// exponential evaluation
1002  /// assert( atype1 <= atype2 ), which is accomplished at the top of this function.
1003  Real const dis_rad1 = dis - lj_radius(atype1);
1004  Real const x1 = ( dis_rad1 * dis_rad1 ) * lk_inv_lambda2_(atype1);
1005  Real const dis_rad2 = dis - lj_radius(atype2);
1006  Real const x2 = ( dis_rad2 * dis_rad2 ) * lk_inv_lambda2_(atype2);
1007 
1008  Real const solvE1 = std::exp(-x1) * p.lk_coeff1 * inv_dis2;
1009  Real const solvE2 = std::exp(-x2) * p.lk_coeff2 * inv_dis2;
1010  dfasolE_ddis = -2 * ( ( dis_rad1 * lk_inv_lambda2_(atype1) + inv_dis ) * solvE1 + ( dis_rad2 * lk_inv_lambda2_(atype2) + inv_dis ) * solvE2 );
1011  dfasolE_ddis *= p.fasol_final_weight;
1012 
1013  } else if ( dis < fasol_spline_far_xhi ) {
1014  dfasolE_ddis = spline_deriv( dis,
1017  p.fasol_spline_far ) *
1018  p.fasol_final_weight;
1019  } else {
1020  dfasolE_ddis = 0;
1021  }
1022 }
1023 
1024 //void
1025 //Etable::analytic_etable_evaluation_H(
1026 // conformation::Atom const & at1,
1027 // conformation::Atom const & at2,
1028 // EtableParamsOnePair const & p,
1029 // Real const dis2,
1030 // Real & lj_atrE,
1031 // Real & lj_repE,
1032 // Real & fa_solE
1033 //) const
1034 //{
1035 // assert( dis2 <= p.maxd2 );
1036 // if ( dis2 < p.ljrep_linear_ramp_d2_cutoff ) {
1037 // // ctsa - use linear ramp instead of lj when the dis/sigma
1038 // // ratio drops below theshold
1039 // Real dis = std::sqrt( dis2 );
1040 // lj_repE = analytic_ljrep_linearized( dis, p ) - p.lj_val_at_minimum;
1041 // } else {
1042 // lj_repE = analytic_lj_generic_form( 1/dis2, p ) - p.lj_val_at_minimum;
1043 // }
1044 //}
1045 
1046 /// @details only to be called when the distance, dis, is less than the switch-point for
1047 /// the lj_switch_dis2sigma value.
1048 inline
1049 Real
1051  Real const dis,
1052  EtableParamsOnePair const & p
1053 ) const
1054 {
1055  assert( dis * dis < p.ljrep_linear_ramp_d2_cutoff );
1056  return dis*p.lj_switch_slope + p.lj_switch_intercept;
1057 }
1058 
1059 /// @details: evaluate the standard Lennard-Jones 6-12 functional form.
1060 /// Only call this function if the square distance is in the range
1061 /// sqrt( p.ljrep_linear_ramp_d2_cutoff ) < dis < p.ljatr_spline_xhi
1062 inline
1063 Real
1065  Real const ASSERT_ONLY( dis2 ),
1066  Real const inv_dis2,
1067  EtableParamsOnePair const & p
1068 ) const
1069 {
1070  assert( dis2 >= p.ljrep_linear_ramp_d2_cutoff );
1071  assert( dis2 <= p.ljatr_spline_xhi * p.ljatr_spline_xhi );
1072  Real const inv_dis6 = inv_dis2 * inv_dis2 * inv_dis2;
1073  //Real const inv_dis12 = inv_dis6 * inv_dis6;
1074 
1075  return ( p.lj_r12_coeff * inv_dis6 + p.lj_r6_coeff ) * inv_dis6;
1076 }
1077 
1078 inline
1079 Real
1081  Real const x,
1082  Real const xlo,
1083  Real const xhi,
1084  SplineParameters const & sp
1085 )
1086 {
1087  assert( x >= xlo && x <= xhi );
1088  Real width = xhi - xlo;
1089  return eval_spline( x, xlo, xhi, width, 1/width, sp );
1090 }
1091 
1092 inline
1093 Real
1095  Real const x,
1096  Real const xlo,
1097  Real const xhi,
1098  SplineParameters const & sp
1099 )
1100 {
1101  assert( x >= xlo && x <= xhi );
1102  Real width = xhi - xlo;
1103  return spline_deriv( x, xlo, xhi, width, 1/width, sp );
1104 }
1105 
1106 inline
1107 Real
1109  Real const x,
1110  Real const xlo,
1111  Real const xhi,
1112  Real const width,
1113  Real const invwidth,
1114  SplineParameters const & sp
1115 )
1116 {
1117  Real a = ( xhi - x ) * invwidth;
1118  Real b = ( x - xlo ) * invwidth;
1119  return a*sp.ylo + b*sp.yhi + ((a*a*a-a)*sp.y2lo + (b*b*b-b)*sp.y2hi)*width*width / 6;
1120 }
1121 
1122 inline
1123 Real
1125  Real const x,
1126  Real const xlo,
1127  Real const xhi,
1128  Real const width,
1129  Real const invwidth,
1130  SplineParameters const & sp
1131 )
1132 {
1133  Real a = ( xhi - x ) * invwidth;
1134  Real b = ( x - xlo ) * invwidth;
1135  return -1*invwidth*sp.ylo + invwidth*sp.yhi + ((1 - 3*a*a )*sp.y2lo + (3*b*b - 1 )*sp.y2hi)*width / 6;
1136 }
1137 
1138 /// @details: evaluate the attractive component of the LJ term as it
1139 /// ramps to zero.
1140 /// Only call this function if the square distance is in the range
1141 /// p.ljatr_spline_xlo < dis < p.ljatr_spline_xhi
1142 inline
1143 Real
1145  Real const dis,
1146  EtableParamsOnePair const & p
1147 ) const
1148 {
1149  assert( dis >= p.ljatr_spline_xlo );
1150  assert( dis <= p.ljatr_spline_xhi );
1152 }
1153 
1154 /// @details: evaluate the derivative for the attractive component
1155 /// of the LJ term as it ramps to zero.
1156 /// Only call this function if the square distance is in the range
1157 /// p.ljatr_spline_xlo < dis < p.ljatr_spline_xhi
1158 inline
1159 Real
1161  Real const dis,
1162  EtableParamsOnePair const & p
1163 ) const
1164 {
1165  assert( dis >= p.ljatr_spline_xlo );
1166  assert( dis <= p.ljatr_spline_xhi );
1168 }
1169 
1170 inline
1171 EtableParamsOnePair const &
1173  Size atype1,
1174  Size atype2
1175 ) const
1176 {
1177  Size i1 = atype1 < atype2 ? atype1 : atype2;
1178  Size i2 = atype1 < atype2 ? atype2 : atype1;
1179  Size index = (i1-1)*n_atomtypes_ + i2 - (i1*(i1-1)/2 );
1180  return analytic_parameters[ index ];
1181 }
1182 
1183 inline
1186  Size atype1,
1187  Size atype2
1188 )
1189 {
1190  Size i1 = atype1 < atype2 ? atype1 : atype2;
1191  Size i2 = atype1 < atype2 ? atype2 : atype1;
1192  Size index = (i1-1)*n_atomtypes_ + i2 - (i1*(i1-1)/2 );
1193  return analytic_parameters[ index ];
1194 }
1195 
1196 
1197 
1198 } // etable
1199 } // scoring
1200 } // core
1201 
1202 #endif