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
12 public ShakeChargeConstraint(int nConstraints, int c, double tol){
13 this.nConstraints = nConstraints;
14 this.c = c;
15 this.tol = tol;
16 }
17 @Override
18 public void applyConstraintToStep(final double[] xPrior, double[] xNew, final double[] masses, double tol){
19 }
20
21 public boolean applyChargeConstraintToStep( final double[] x, final double[] a, final double[] masses, final double dt){
22 boolean done = true;
23
24 double totalLambda = 0.0;
25 double totalInverseMass = 0.0;
26 for (int i = 0; i < nConstraints; i++) {
27 double lambda = Math.sin(x[i]) * Math.sin(x[i]);
28 totalLambda += lambda;
29 totalInverseMass += (1.0 / masses[i]);
30 }
31 double delta = totalLambda - c;
32
33 if (Math.abs(delta) > tol) {
34 done = false;
35 double term = delta / (dt * dt * totalInverseMass);
36 for (int i = 0; i < nConstraints; i++) {
37
38 a[i] = -KCAL_TO_GRAM_ANG2_PER_PS2 * term * Math.sin(2 * x[i]) / masses[i];
39 }
40 }
41 return done;
42 }
43
44 @Override
45 public void applyConstraintToVelocities(final double[] x, double[] v, final double[] masses, double tol){
46
47 }
48
49 @Override
50 public int[] constrainedAtomIndices() {
51 return new int[0];
52 }
53
54 @Override
55 public boolean constraintSatisfied(double[] x, double tol) {
56 return false;
57 }
58
59 @Override
60 public boolean constraintSatisfied(double[] x, double[] v, double xTol, double vTol) {
61 return false;
62 }
63
64 @Override
65 public int getNumDegreesFrozen() {
66 return 0;
67 }
68 }
69
70