View Javadoc
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  }