1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.potential.openmm;
39
40 import ffx.openmm.Force;
41 import ffx.openmm.PeriodicTorsionForce;
42 import ffx.potential.bonded.ImproperTorsion;
43 import ffx.potential.parameters.ImproperTorsionType;
44
45 import java.util.logging.Level;
46 import java.util.logging.Logger;
47
48 import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_KJPerKcal;
49 import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_RadiansPerDegree;
50 import static java.lang.String.format;
51
52
53
54
55 public class ImproperTorsionForce extends PeriodicTorsionForce {
56
57 private static final Logger logger = Logger.getLogger(ImproperTorsionForce.class.getName());
58
59 private double lambdaTorsion = 1.0;
60
61
62
63
64
65
66 public ImproperTorsionForce(OpenMMEnergy openMMEnergy) {
67 ImproperTorsion[] improperTorsions = openMMEnergy.getImproperTorsions();
68 if (improperTorsions == null || improperTorsions.length < 1) {
69
70 destroy();
71 return;
72 }
73
74 for (ImproperTorsion improperTorsion : improperTorsions) {
75 int a1 = improperTorsion.getAtom(0).getXyzIndex() - 1;
76 int a2 = improperTorsion.getAtom(1).getXyzIndex() - 1;
77 int a3 = improperTorsion.getAtom(2).getXyzIndex() - 1;
78 int a4 = improperTorsion.getAtom(3).getXyzIndex() - 1;
79 ImproperTorsionType type = improperTorsion.improperType;
80 double forceConstant = OpenMM_KJPerKcal * type.impTorUnit * improperTorsion.scaleFactor * type.k;
81 addTorsion(a1, a2, a3, a4, type.periodicity, type.phase * OpenMM_RadiansPerDegree, forceConstant);
82 }
83
84 int forceGroup = openMMEnergy.getMolecularAssembly().getForceField().getInteger("IMPROPER_TORSION_FORCE_GROUP", 0);
85 setForceGroup(forceGroup);
86 logger.info(format(" Improper Torsions: %10d", improperTorsions.length));
87 logger.fine(format(" Force Group: %10d", forceGroup));
88 }
89
90
91
92
93
94
95 public void setLambdaTorsion(double lambdaTorsion) {
96 this.lambdaTorsion = lambdaTorsion;
97 }
98
99
100
101
102
103
104
105 public static Force constructForce(OpenMMEnergy openMMEnergy) {
106 ImproperTorsion[] improperTorsions = openMMEnergy.getImproperTorsions();
107 if (improperTorsions == null || improperTorsions.length < 1) {
108 return null;
109 }
110 return new ImproperTorsionForce(openMMEnergy);
111 }
112
113
114
115
116
117
118 public void updateForce(OpenMMEnergy openMMEnergy) {
119 ImproperTorsion[] improperTorsions = openMMEnergy.getImproperTorsions();
120 if (improperTorsions == null || improperTorsions.length < 1) {
121 return;
122 }
123
124 int nImproperTorsions = improperTorsions.length;
125 for (int i = 0; i < nImproperTorsions; i++) {
126 ImproperTorsion improperTorsion = improperTorsions[i];
127 int a1 = improperTorsion.getAtom(0).getXyzIndex() - 1;
128 int a2 = improperTorsion.getAtom(1).getXyzIndex() - 1;
129 int a3 = improperTorsion.getAtom(2).getXyzIndex() - 1;
130 int a4 = improperTorsion.getAtom(3).getXyzIndex() - 1;
131 ImproperTorsionType type = improperTorsion.improperType;
132 double forceConstant = OpenMM_KJPerKcal * type.impTorUnit * improperTorsion.scaleFactor * type.k * lambdaTorsion;
133 setTorsionParameters(i, a1, a2, a3, a4, type.periodicity, type.phase * OpenMM_RadiansPerDegree, forceConstant);
134 }
135
136 updateParametersInContext(openMMEnergy.getContext());
137 }
138
139 }