29 #ifndef CDPL_FORCEFIELD_MMFF94ENERGYFUNCTIONS_HPP
30 #define CDPL_FORCEFIELD_MMFF94ENERGYFUNCTIONS_HPP
48 template <
typename ValueType,
typename Iter,
typename CoordsArray>
51 template <
typename ValueType,
typename CoordsArray>
77 template <
typename ValueType,
typename CoordsVec>
79 const ValueType& force_const,
const ValueType& ref_length);
103 template <
typename ValueType>
107 template <
typename ValueType,
typename Iter,
typename CoordsArray>
110 template <
typename ValueType,
typename CoordsArray>
141 template <
typename ValueType,
typename CoordsVec>
143 bool linear,
const ValueType& force_const,
const ValueType& ref_angle);
175 template <
typename ValueType,
typename CoordsVec>
177 const ValueType& r_ij,
const ValueType& r_jk,
178 bool linear,
const ValueType& force_const,
const ValueType& ref_angle);
181 template <
typename ValueType,
typename Iter,
typename CoordsArray>
184 template <
typename ValueType,
typename CoordsArray>
217 template <
typename ValueType,
typename CoordsVec>
219 const ValueType& ijk_force_const,
const ValueType& kji_force_const,
const ValueType& ref_angle,
220 const ValueType& ref_length1,
const ValueType& ref_length2);
254 template <
typename ValueType,
typename CoordsVec>
256 const ValueType& r_ij,
const ValueType& r_jk,
257 const ValueType& ijk_force_const,
const ValueType& kji_force_const,
const ValueType& ref_angle,
258 const ValueType& ref_length1,
const ValueType& ref_length2);
261 template <
typename ValueType,
typename Iter,
typename CoordsArray>
264 template <
typename ValueType,
typename CoordsArray>
284 template <
typename ValueType,
typename CoordsVec>
286 const CoordsVec& oop_atom_pos,
const ValueType& force_const);
306 template <
typename ValueType,
typename CoordsVec>
308 const CoordsVec& oop_atom_pos,
const ValueType& r_jl,
const ValueType& force_const);
311 template <
typename ValueType,
typename Iter,
typename CoordsArray>
314 template <
typename ValueType,
typename CoordsArray>
338 template <
typename ValueType,
typename CoordsVec>
339 ValueType
calcMMFF94TorsionEnergy(
const CoordsVec& term_atom1_pos,
const CoordsVec& ctr_atom1_pos,
const CoordsVec& ctr_atom2_pos,
340 const CoordsVec& term_atom2_pos,
const ValueType& tor_param1,
const ValueType& tor_param2,
341 const ValueType& tor_param3);
344 template <
typename ValueType,
typename Iter,
typename CoordsArray>
347 template <
typename ValueType,
typename CoordsArray>
376 template <
typename ValueType,
typename CoordsVec>
378 const ValueType& atom2_chg,
const ValueType& scale_fact,
const ValueType& de_const,
379 const ValueType& dist_expo);
406 template <
typename ValueType>
408 const ValueType& scale_fact,
const ValueType& de_const,
const ValueType& dist_expo);
411 template <
typename ValueType,
typename Iter,
typename CoordsArray>
414 template <
typename ValueType,
typename CoordsArray>
452 template <
typename ValueType,
typename CoordsVec>
454 const ValueType& r_IJ,
const ValueType& r_IJ_7);
490 template <
typename ValueType>
492 const ValueType& r_IJ,
const ValueType& r_IJ_7);
509 template <
typename ValueType,
typename Iter,
typename CoordsArray,
typename FuncType>
510 ValueType accumMMFF94InteractionEnergies(Iter& beg,
const Iter& end,
const CoordsArray& coords,
const FuncType& func)
512 ValueType e = ValueType();
514 for (; beg != end; ++beg)
515 e += func(*beg, coords);
524 template <
typename ValueType,
typename Iter,
typename CoordsArray>
527 return Detail::accumMMFF94InteractionEnergies<ValueType>(beg, end, coords,
528 static_cast<ValueType (*)(
const MMFF94BondStretchingInteraction&,
const CoordsArray&)
>(
529 &calcMMFF94BondStretchingEnergy<ValueType, CoordsArray>));
532 template <
typename ValueType,
typename CoordsArray>
535 return calcMMFF94BondStretchingEnergy<ValueType>(coords[iaction.getAtom1Index()], coords[iaction.getAtom2Index()],
536 iaction.getForceConstant(), iaction.getReferenceLength());
539 template <
typename ValueType,
typename CoordsVec>
541 const ValueType& force_const,
const ValueType& ref_length)
543 ValueType dr_ij = calcDistance<ValueType>(atom1_pos, atom2_pos) - ref_length;
544 ValueType dr_ij_2 = dr_ij * dr_ij;
545 ValueType e_b = ValueType(143.9325 * 0.5) * force_const * dr_ij_2 * (1 - 2 * dr_ij + 28 * dr_ij_2 / 12);
550 template <
typename ValueType>
553 ValueType dr_ij = r_ij - ref_length;
554 ValueType dr_ij_2 = dr_ij * dr_ij;
555 ValueType e_b = ValueType(143.9325 * 0.5) * force_const * dr_ij_2 * (1 - 2 * dr_ij + 28 * dr_ij_2 / 12);
561 template <
typename ValueType,
typename Iter,
typename CoordsArray>
564 return Detail::accumMMFF94InteractionEnergies<ValueType>(beg, end, coords,
565 static_cast<ValueType (*)(
const MMFF94AngleBendingInteraction&,
const CoordsArray&)
>(
566 &calcMMFF94AngleBendingEnergy<ValueType, CoordsArray>));
569 template <
typename ValueType,
typename CoordsArray>
572 return calcMMFF94AngleBendingEnergy<ValueType>(coords[iaction.getTerminalAtom1Index()], coords[iaction.getCenterAtomIndex()],
573 coords[iaction.getTerminalAtom2Index()], iaction.isLinearAngle(), iaction.getForceConstant(),
574 iaction.getReferenceAngle());
577 template <
typename ValueType,
typename CoordsVec>
579 bool linear,
const ValueType& force_const,
const ValueType& ref_angle)
582 return (ValueType(143.9325) * force_const * (1 + calcBondAngleCos<ValueType>(term_atom1_pos, ctr_atom_pos, term_atom2_pos)));
584 ValueType a_ijk = calcBondAngle<ValueType>(term_atom1_pos, ctr_atom_pos, term_atom2_pos) * ValueType(180 / M_PI);
585 ValueType da_ijk = a_ijk - ref_angle;
586 ValueType e_a = ValueType(0.043844 * 0.5) * force_const * da_ijk * da_ijk * (1 - ValueType(0.007) * da_ijk);
591 template <
typename ValueType,
typename CoordsVec>
593 const ValueType& r_ij,
const ValueType& r_jk,
594 bool linear,
const ValueType& force_const,
const ValueType& ref_angle)
597 return (ValueType(143.9325) * force_const * (1 + calcBondAngleCos<ValueType>(term_atom1_pos, ctr_atom_pos, term_atom2_pos, r_ij, r_jk)));
599 ValueType a_ijk = calcBondAngle<ValueType>(term_atom1_pos, ctr_atom_pos, term_atom2_pos, r_ij, r_jk) * ValueType(180 / M_PI);
600 ValueType da_ijk = a_ijk - ref_angle;
601 ValueType e_a = ValueType(0.043844 * 0.5) * force_const * da_ijk * da_ijk * (1 - ValueType(0.007) * da_ijk);
607 template <
typename ValueType,
typename Iter,
typename CoordsArray>
610 return Detail::accumMMFF94InteractionEnergies<ValueType>(beg, end, coords,
611 static_cast<ValueType (*)(
const MMFF94StretchBendInteraction&,
const CoordsArray&)
>(
612 &calcMMFF94StretchBendEnergy<ValueType, CoordsArray>));
615 template <
typename ValueType,
typename CoordsArray>
618 return calcMMFF94StretchBendEnergy<ValueType>(coords[iaction.getTerminalAtom1Index()], coords[iaction.getCenterAtomIndex()],
619 coords[iaction.getTerminalAtom2Index()], iaction.getIJKForceConstant(),
620 iaction.getKJIForceConstant(), iaction.getReferenceAngle(), iaction.getReferenceLength1(),
621 iaction.getReferenceLength2());
624 template <
typename ValueType,
typename CoordsVec>
626 const ValueType& ijk_force_const,
const ValueType& kji_force_const,
const ValueType& ref_angle,
627 const ValueType& ref_length1,
const ValueType& ref_length2)
629 ValueType r_ij = ValueType();
630 ValueType r_kj = ValueType();
631 ValueType a_ijk =
calcBondLengthsAndAngle(term_atom1_pos, ctr_atom_pos, term_atom2_pos, r_ij, r_kj) * ValueType(180 / M_PI);
633 ValueType dr_ij = r_ij - ref_length1;
634 ValueType dr_kj = r_kj - ref_length2;
635 ValueType da_ijk = a_ijk - ref_angle;
637 ValueType e_ab = ValueType(2.51210) * (ijk_force_const * dr_ij + kji_force_const * dr_kj) * da_ijk;
642 template <
typename ValueType,
typename CoordsVec>
644 const ValueType& r_ij,
const ValueType& r_jk,
645 const ValueType& ijk_force_const,
const ValueType& kji_force_const,
const ValueType& ref_angle,
646 const ValueType& ref_length1,
const ValueType& ref_length2)
648 ValueType a_ijk =
calcBondAngle(term_atom1_pos, ctr_atom_pos, term_atom2_pos, r_ij, r_jk) * ValueType(180 / M_PI);
650 ValueType dr_ij = r_ij - ref_length1;
651 ValueType dr_kj = r_jk - ref_length2;
652 ValueType da_ijk = a_ijk - ref_angle;
654 ValueType e_ab = ValueType(2.51210) * (ijk_force_const * dr_ij + kji_force_const * dr_kj) * da_ijk;
660 template <
typename ValueType,
typename Iter,
typename CoordsArray>
663 return Detail::accumMMFF94InteractionEnergies<ValueType>(beg, end, coords,
664 static_cast<ValueType (*)(
const MMFF94OutOfPlaneBendingInteraction&,
const CoordsArray&)
>(
665 &calcMMFF94OutOfPlaneBendingEnergy<ValueType, CoordsArray>));
668 template <
typename ValueType,
typename CoordsArray>
671 return calcMMFF94OutOfPlaneBendingEnergy<ValueType>(coords[iaction.getTerminalAtom1Index()], coords[iaction.getCenterAtomIndex()],
672 coords[iaction.getTerminalAtom2Index()], coords[iaction.getOutOfPlaneAtomIndex()],
673 iaction.getForceConstant());
676 template <
typename ValueType,
typename CoordsVec>
678 const CoordsVec& oop_atom_pos,
const ValueType& force_const)
680 ValueType chi_ijkl = calcOutOfPlaneAngle<ValueType>(term_atom1_pos, ctr_atom_pos, term_atom2_pos, oop_atom_pos) * ValueType(180 / M_PI);
681 ValueType e_oop = ValueType(0.5 * 0.043844) * force_const * chi_ijkl * chi_ijkl;
686 template <
typename ValueType,
typename CoordsVec>
688 const CoordsVec& oop_atom_pos,
const ValueType& r_jl,
const ValueType& force_const)
690 ValueType chi_ijkl = calcOutOfPlaneAngle<ValueType>(term_atom1_pos, ctr_atom_pos, term_atom2_pos, oop_atom_pos, r_jl) * ValueType(180 / M_PI);
691 ValueType e_oop = ValueType(0.5 * 0.043844) * force_const * chi_ijkl * chi_ijkl;
697 template <
typename ValueType,
typename Iter,
typename CoordsArray>
700 return Detail::accumMMFF94InteractionEnergies<ValueType>(beg, end, coords,
701 static_cast<ValueType (*)(
const MMFF94TorsionInteraction&,
const CoordsArray&)
>(
702 &calcMMFF94TorsionEnergy<ValueType, CoordsArray>));
705 template <
typename ValueType,
typename CoordsArray>
708 return calcMMFF94TorsionEnergy<ValueType>(coords[iaction.getTerminalAtom1Index()], coords[iaction.getCenterAtom1Index()],
709 coords[iaction.getCenterAtom2Index()], coords[iaction.getTerminalAtom2Index()],
710 iaction.getTorsionParameter1(), iaction.getTorsionParameter2(), iaction.getTorsionParameter3());
713 template <
typename ValueType,
typename CoordsVec>
715 const CoordsVec& term_atom2_pos,
const ValueType& tor_param1,
const ValueType& tor_param2,
716 const ValueType& tor_param3)
718 ValueType phi_cos = calcDihedralAngleCos<ValueType>(term_atom1_pos, ctr_atom1_pos, ctr_atom2_pos, term_atom2_pos);
719 ValueType phi = std::acos(phi_cos);
720 ValueType e_t = ValueType(0.5) * (tor_param1 * (1 + phi_cos) + tor_param2 * (1 - std::cos(2 * phi)) + tor_param3 * (1 + std::cos(3 * phi)));
726 template <
typename ValueType,
typename Iter,
typename CoordsArray>
729 return Detail::accumMMFF94InteractionEnergies<ValueType>(beg, end, coords,
730 static_cast<ValueType (*)(
const MMFF94ElectrostaticInteraction&,
const CoordsArray&)
>(
731 &calcMMFF94ElectrostaticEnergy<ValueType, CoordsArray>));
734 template <
typename ValueType,
typename CoordsArray>
737 return calcMMFF94ElectrostaticEnergy<ValueType>(coords[iaction.getAtom1Index()], coords[iaction.getAtom2Index()],
738 iaction.getAtom1Charge(), iaction.getAtom2Charge(), iaction.getScalingFactor(),
739 iaction.getDielectricConstant(), iaction.getDistanceExponent());
742 template <
typename ValueType,
typename CoordsVec>
744 const ValueType& atom2_chg,
const ValueType& scale_fact,
const ValueType& de_const,
745 const ValueType& dist_expo)
747 ValueType tmp = std::pow(calcDistance<ValueType>(atom1_pos, atom2_pos) + ValueType(0.05), dist_expo);
748 ValueType e_q = scale_fact * ValueType(332.0716) * atom1_chg * atom2_chg / (de_const * tmp);
753 template <
typename ValueType>
755 const ValueType& scale_fact,
const ValueType& de_const,
const ValueType& dist_expo)
757 ValueType tmp = std::pow(r_ij + ValueType(0.05), dist_expo);
758 ValueType e_q = scale_fact * ValueType(332.0716) * atom1_chg * atom2_chg / (de_const * tmp);
764 template <
typename ValueType,
typename Iter,
typename CoordsArray>
767 return Detail::accumMMFF94InteractionEnergies<ValueType>(beg, end, coords,
768 static_cast<ValueType (*)(
const MMFF94VanDerWaalsInteraction&,
const CoordsArray&)
>(
769 &calcMMFF94VanDerWaalsEnergy<ValueType, CoordsArray>));
772 template <
typename ValueType,
typename CoordsArray>
775 return calcMMFF94VanDerWaalsEnergy<ValueType>(coords[iaction.getAtom1Index()], coords[iaction.getAtom2Index()],
776 iaction.getEIJ(), iaction.getRIJ(), iaction.getRIJPow7());
779 template <
typename ValueType,
typename CoordsVec>
781 const ValueType& r_IJ,
const ValueType& r_IJ_7)
783 ValueType r_ij_2 = calcSquaredDistance<ValueType>(atom1_pos, atom2_pos);
784 ValueType r_ij = std::sqrt(r_ij_2);
785 ValueType r_ij_7 = r_ij_2 * r_ij_2 * r_ij_2 * r_ij;
787 ValueType tmp = ValueType(1.07) * r_IJ / (r_ij + ValueType(0.07) * r_IJ);
788 ValueType tmp_2 = tmp * tmp;
789 ValueType tmp_7 = tmp_2 * tmp_2 * tmp_2 * tmp;
791 ValueType e_vdw = e_IJ * tmp_7 * (ValueType(1.12) * r_IJ_7 / (r_ij_7 + ValueType(0.12) * r_IJ_7) - 2);
796 template <
typename ValueType>
798 const ValueType& r_IJ,
const ValueType& r_IJ_7)
800 ValueType r_ij_2 = r_ij * r_ij;
801 ValueType r_ij_7 = r_ij_2 * r_ij_2 * r_ij_2 * r_ij;
803 ValueType tmp = ValueType(1.07) * r_IJ / (r_ij + ValueType(0.07) * r_IJ);
804 ValueType tmp_2 = tmp * tmp;
805 ValueType tmp_7 = tmp_2 * tmp_2 * tmp_2 * tmp;
807 ValueType e_vdw = e_IJ * tmp_7 * (ValueType(1.12) * r_IJ_7 / (r_ij_7 + ValueType(0.12) * r_IJ_7) - 2);
814 #endif // CDPL_FORCEFIELD_MMFF94ENERGYFUNCTIONS_HPP