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.log(Level.INFO, format(" Improper Torsions \t%6d\t\t%1d", improperTorsions.length, forceGroup));
87 }
88
89
90
91
92
93
94 public void setLambdaTorsion(double lambdaTorsion) {
95 this.lambdaTorsion = lambdaTorsion;
96 }
97
98
99
100
101
102
103
104 public static Force constructForce(OpenMMEnergy openMMEnergy) {
105 ImproperTorsion[] improperTorsions = openMMEnergy.getImproperTorsions();
106 if (improperTorsions == null || improperTorsions.length < 1) {
107 return null;
108 }
109 return new ImproperTorsionForce(openMMEnergy);
110 }
111
112
113
114
115
116
117 public void updateForce(OpenMMEnergy openMMEnergy) {
118 ImproperTorsion[] improperTorsions = openMMEnergy.getImproperTorsions();
119 if (improperTorsions == null || improperTorsions.length < 1) {
120 return;
121 }
122
123 int nImproperTorsions = improperTorsions.length;
124 for (int i = 0; i < nImproperTorsions; i++) {
125 ImproperTorsion improperTorsion = improperTorsions[i];
126 int a1 = improperTorsion.getAtom(0).getXyzIndex() - 1;
127 int a2 = improperTorsion.getAtom(1).getXyzIndex() - 1;
128 int a3 = improperTorsion.getAtom(2).getXyzIndex() - 1;
129 int a4 = improperTorsion.getAtom(3).getXyzIndex() - 1;
130 ImproperTorsionType type = improperTorsion.improperType;
131 double forceConstant = OpenMM_KJPerKcal * type.impTorUnit * improperTorsion.scaleFactor * type.k * lambdaTorsion;
132 setTorsionParameters(i, a1, a2, a3, a4, type.periodicity, type.phase * OpenMM_RadiansPerDegree, forceConstant);
133 }
134
135 updateParametersInContext(openMMEnergy.getContext());
136 }
137
138 }