1 package ffx.potential.constraint;
2
3 import ffx.numerics.Constraint;
4
5 import static ffx.utilities.Constants.KCAL_TO_GRAM_ANG2_PER_PS2;
6
7 public class ShakeChargeConstraint implements Constraint {
8 final int nConstraints;
9 final double tol;
10 final int c;
11 final double maxIters = 150;
12
13 public ShakeChargeConstraint(int nConstraints, int c, double tol){
14 this.nConstraints = nConstraints;
15 this.c = c;
16 this.tol = tol;
17 }
18 @Override
19 public void applyConstraintToStep(final double[] xPrior, double[] xNew, final double[] masses, double tol){
20 }
21
22
23
24
25
26
27
28
29
30 public void applyChargeConstraintToStep(final double[] x, final double[] masses){
31 boolean done = false;
32 int iter = 0;
33 while(!done){
34 done = true;
35 iter++;
36 double totalLambda = 0.0;
37 double totalInverseMass = 0.0;
38 for (int i = 0; i < nConstraints; i++) {
39 double lambda = Math.sin(x[i]) * Math.sin(x[i]);
40 totalLambda += lambda;
41 totalInverseMass += (1.0 / masses[i]);
42 }
43 double delta = totalLambda - c;
44 if (Math.abs(delta) > tol) {
45 done = false;
46 double term = delta / totalInverseMass;
47 for (int i = 0; i < nConstraints; i++) {
48 double g = -term * Math.sin(2 * x[i]);
49
50 x[i] = x[i] - (g * -KCAL_TO_GRAM_ANG2_PER_PS2 / masses[i]) * 0.01;
51 }
52 }
53 if(iter >= maxIters){
54 throw new RuntimeException("SHAKE Charge Constraint -- Warning, Charge Constraint not Satisfied");
55 }
56 }
57 }
58
59 @Override
60 public void applyConstraintToVelocities(final double[] x, double[] v, final double[] masses, double tol){
61
62 }
63
64 @Override
65 public int[] constrainedAtomIndices() {
66 return new int[0];
67 }
68
69 @Override
70 public boolean constraintSatisfied(double[] x, double tol) {
71 return false;
72 }
73
74 @Override
75 public boolean constraintSatisfied(double[] x, double[] v, double xTol, double vTol) {
76 return false;
77 }
78
79 @Override
80 public int getNumDegreesFrozen() {
81 return 0;
82 }
83 }
84
85