1 package ffx.numerics.multipole;
2
3 /**
4 * This class allows for the source terms of tensors to be combined, and therefore
5 * multiple interaction tensors can be computed simultaneously (as a sum).
6 * <p>
7 * Non-Ex. Amoeba = M-pole*(Ewald)*M-pole + self
8 * Ex. Amoeba PolarizationE = Dipole*(Coulomb - Thole)*M-pol
9 * Ex. Amoeba SCF Eval = Dipole*(permPolField + (Coulomb - Thole)*Dipole) (at convergence goes to A PolE)
10 * <p>
11 * Ex. Amoeba+ = M-pol*(Ewald - CPenOverlap)*M-pol + Core*(Ewald-CPenDamp)*(Mpole) + Core*(Ewald)*Core + self
12 * Ex. Amoeba+ PolE = Dipole*(Ewald - TholeDirect)*M-pol
13 * Ex. Amoeba+ SCF Eval = Dipole(permPolField + (Coulomb - Thole)*Dipole) (at convergence this goes to A+ PolE)
14 */
15 public class CombinedTensorGlobal extends CoulombTensorGlobal {
16
17 private double[] termsToAdd;
18 private double multiplier = 1.0;
19 private double[] termsToAddSep;
20
21 /**
22 * Constructor for CoulombTensorGlobal.
23 *
24 * @param order The order of the tensor.
25 */
26 public CombinedTensorGlobal(int order) {
27 super(order);
28 this.termsToAdd = new double[order + 1];
29 this.termsToAddSep = new double[order + 1];
30 }
31
32 /**
33 * Accumulates onto existing terms. Assumes we add all the elements
34 * onto the respective index on existing array. Implicitly adds coulomb
35 * interaction.
36 *
37 * @param terms The terms to add.
38 */
39 public void addTerms(double[] terms) {
40 assert (terms.length <= this.termsToAdd.length);
41 for (int i = 0; i < terms.length; i++) {
42 this.termsToAdd[i] += terms[i];
43 }
44 }
45
46 /**
47 * Reset the source terms.
48 */
49 public void resetSource() {
50 this.termsToAdd = new double[this.termsToAdd.length];
51 this.termsToAddSep = new double[this.termsToAdd.length];
52 }
53
54 /**
55 * Generate source terms for the Challacombe et al. recursion.
56 *
57 * @param T000 Location to store the source terms.
58 */
59 @Override
60 protected void source(double[] T000) {
61 // Compute the normal Coulomb auxiliary term.
62 super.source(T000); // Important that what is passed into here does not already have coulomb terms in it
63
64 for (int i = 0; i < termsToAdd.length; i++) {
65 T000[i] *= 1 * multiplier + termsToAdd[i]; // multiplier may make coulomb term negative
66 T000[i] += termsToAddSep[i];
67 }
68 }
69
70 /**
71 * Add a multiplier to the Coulomb term.
72 *
73 * @param multiplier The multiplier to add.
74 */
75 public void addCoulombMultiplier(double multiplier) {
76 this.multiplier = multiplier;
77 }
78
79 /**
80 * Accumulates onto existing terms.
81 *
82 * @param terms The terms to add.
83 */
84 public void addTermsSeparate(double[] terms) {
85 assert (terms.length <= this.termsToAddSep.length);
86 for (int i = 0; i < terms.length; i++) {
87 this.termsToAddSep[i] += terms[i];
88 }
89 }
90 }