View Javadoc
1   // ******************************************************************************
2   //
3   // Title:       Force Field X.
4   // Description: Force Field X - Software for Molecular Biophysics.
5   // Copyright:   Copyright (c) Michael J. Schnieders 2001-2024.
6   //
7   // This file is part of Force Field X.
8   //
9   // Force Field X is free software; you can redistribute it and/or modify it
10  // under the terms of the GNU General Public License version 3 as published by
11  // the Free Software Foundation.
12  //
13  // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16  // details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA 02111-1307 USA
21  //
22  // Linking this library statically or dynamically with other modules is making a
23  // combined work based on this library. Thus, the terms and conditions of the
24  // GNU General Public License cover the whole combination.
25  //
26  // As a special exception, the copyright holders of this library give you
27  // permission to link this library with independent modules to produce an
28  // executable, regardless of the license terms of these independent modules, and
29  // to copy and distribute the resulting executable under terms of your choice,
30  // provided that you also meet, for each linked independent module, the terms
31  // and conditions of the license of that module. An independent module is a
32  // module which is not derived from or based on this library. If you modify this
33  // library, you may extend this exception to your version of the library, but
34  // you are not obligated to do so. If you do not wish to do so, delete this
35  // exception statement from your version.
36  //
37  // ******************************************************************************
38  package ffx.potential.nonbonded;
39  
40  import edu.rit.pj.IntegerForLoop;
41  import edu.rit.pj.IntegerSchedule;
42  import java.util.logging.Logger;
43  
44  /**
45   * Loop over a list of atoms and assign their density to a grid.
46   *
47   * @author Michael J. Schnieders
48   * @since 1.0
49   */
50  public abstract class SpatialDensityLoop extends IntegerForLoop {
51  
52    private static final Logger logger = Logger.getLogger(SpatialDensityLoop.class.getName());
53    private int nSymm;
54    private SpatialDensityRegion spatialDensityRegion;
55    private SpatialDensitySchedule spatialDensitySchedule;
56    private int octant = 0;
57  
58    /**
59     * Constructor for SpatialDensityLoop.
60     *
61     * @param region a {@link ffx.potential.nonbonded.SpatialDensityRegion} object.
62     * @param nSymm a int.
63     * @param atomsPerChunk an array of int.
64     */
65    public SpatialDensityLoop(SpatialDensityRegion region, int nSymm, int[] atomsPerChunk) {
66      this.spatialDensityRegion = region;
67      this.nSymm = nSymm;
68      this.spatialDensitySchedule =
69          new SpatialDensitySchedule(region.nThreads, region.nAtoms, atomsPerChunk, 0.97);
70      assert (nSymm <= region.nSymm);
71    }
72  
73    /**
74     * gridDensity
75     *
76     * @param iSymm a int.
77     * @param iAtom a int.
78     */
79    public abstract void gridDensity(int iSymm, int iAtom);
80  
81    /** {@inheritDoc} */
82    @Override
83    public void run(int lb, int ub) {
84      // Loop over work cells
85      for (int icell = lb; icell <= ub; icell++) {
86        int ia = spatialDensityRegion.actualA[icell];
87        int ib = spatialDensityRegion.actualB[icell];
88        int ic = spatialDensityRegion.actualC[icell];
89        switch (octant) {
90            // Case 0 -> In place.
91          case 0:
92            gridCell(ia, ib, ic);
93            break;
94            // Case 1: Step along the C-axis.
95          case 1:
96            gridCell(ia, ib, ic + 1);
97            break;
98            // Case 2 & 3: Step along the B-axis.
99          case 2:
100           gridCell(ia, ib + 1, ic);
101           break;
102         case 3:
103           gridCell(ia, ib + 1, ic + 1);
104           break;
105           // Case 4-7: Step along the A-axis.
106         case 4:
107           gridCell(ia + 1, ib, ic);
108           break;
109         case 5:
110           gridCell(ia + 1, ib, ic + 1);
111           break;
112         case 6:
113           gridCell(ia + 1, ib + 1, ic);
114           break;
115         case 7:
116           gridCell(ia + 1, ib + 1, ic + 1);
117           break;
118         default:
119           String message = "Programming error in PermanentDensityLoop.\n";
120           logger.severe(message);
121       }
122     }
123   }
124 
125   /** {@inheritDoc} */
126   @Override
127   public IntegerSchedule schedule() {
128     return spatialDensitySchedule;
129   }
130 
131   /**
132    * setNsymm
133    *
134    * @param nSymm a int.
135    */
136   public void setNsymm(int nSymm) {
137     this.nSymm = nSymm;
138     assert (nSymm <= spatialDensityRegion.nSymm);
139   }
140 
141   /**
142    * Setter for the field <code>octant</code>.
143    *
144    * @param octant a int.
145    * @return a {@link ffx.potential.nonbonded.SpatialDensityLoop} object.
146    */
147   public SpatialDensityLoop setOctant(int octant) {
148     this.octant = octant;
149     return this;
150   }
151 
152   /**
153    * setRegion.
154    *
155    * @param spatialDensityRegion a {@link ffx.potential.nonbonded.SpatialDensityRegion} object.
156    */
157   public void setRegion(SpatialDensityRegion spatialDensityRegion) {
158     this.spatialDensityRegion = spatialDensityRegion;
159     this.spatialDensitySchedule =
160         new SpatialDensitySchedule(
161             spatialDensityRegion.nThreads,
162             spatialDensityRegion.nAtoms,
163             spatialDensityRegion.actualCount,
164             0.97);
165   }
166 
167   private void gridCell(int ia, int ib, int ic) {
168     for (int iSymm = 0; iSymm < nSymm; iSymm++) {
169       final int[] pairList = spatialDensityRegion.cellList[iSymm];
170       final int index = spatialDensityRegion.index(ia, ib, ic);
171       final int start = spatialDensityRegion.cellStart[iSymm][index];
172       final int stop = start + spatialDensityRegion.cellCount[iSymm][index];
173       for (int i = start; i < stop; i++) {
174         int n = pairList[i];
175         gridDensity(iSymm, n);
176       }
177     }
178   }
179 }