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.pme;
39  
40  import edu.rit.pj.IntegerForLoop;
41  import edu.rit.pj.IntegerSchedule;
42  import edu.rit.pj.ParallelRegion;
43  import edu.rit.pj.ParallelTeam;
44  import ffx.crystal.Crystal;
45  import ffx.crystal.SymOp;
46  import ffx.potential.bonded.Atom;
47  import java.util.List;
48  import java.util.logging.Level;
49  import java.util.logging.Logger;
50  
51  /**
52   * Parallel expansion of the asymmetric unit induced dipoles to symmetry mates by applying symmetry
53   * operator rotation matrices.
54   *
55   * @author Michael J. Schnieders
56   * @since 1.0
57   */
58  public class ExpandInducedDipolesRegion extends ParallelRegion {
59  
60    private static final Logger logger = Logger.getLogger(ExpandInducedDipolesRegion.class.getName());
61    private final ExpandInducedDipoleLoop[] expandInducedDipoleLoop;
62    /** Dimensions of [nsymm][nAtoms][3] */
63    public double[][][] inducedDipole;
64  
65    public double[][][] inducedDipoleCR;
66    /** An ordered array of atoms in the system. */
67    private Atom[] atoms;
68    /** Unit cell and spacegroup information. */
69    private Crystal crystal;
70  
71    public ExpandInducedDipolesRegion(int maxThreads) {
72      expandInducedDipoleLoop = new ExpandInducedDipoleLoop[maxThreads];
73      for (int i = 0; i < maxThreads; i++) {
74        expandInducedDipoleLoop[i] = new ExpandInducedDipoleLoop();
75      }
76    }
77  
78    /**
79     * Execute the ExpandInducedDipolesRegion with the passed ParallelTeam.
80     *
81     * @param parallelTeam The ParallelTeam instance to execute with.
82     */
83    public void executeWith(ParallelTeam parallelTeam) {
84      try {
85        parallelTeam.execute(this);
86      } catch (Exception e) {
87        String message = " Exception expanding induced dipoles.\n";
88        logger.log(Level.WARNING, message, e);
89      }
90    }
91  
92    public void init(
93        Atom[] atoms, Crystal crystal, double[][][] inducedDipole, double[][][] inducedDipoleCR) {
94      // Input
95      this.atoms = atoms;
96      this.crystal = crystal;
97      // Output
98      this.inducedDipole = inducedDipole;
99      this.inducedDipoleCR = inducedDipoleCR;
100   }
101 
102   @Override
103   public void run() {
104     try {
105       int nAtoms = atoms.length;
106       execute(0, nAtoms - 1, expandInducedDipoleLoop[getThreadIndex()]);
107     } catch (Exception e) {
108       String message =
109           "Fatal exception expanding coordinates in thread: " + getThreadIndex() + "\n";
110       logger.log(Level.SEVERE, message, e);
111     }
112   }
113 
114   private class ExpandInducedDipoleLoop extends IntegerForLoop {
115 
116     @Override
117     public void run(int lb, int ub) {
118       List<SymOp> symOps = crystal.spaceGroup.symOps;
119       int nSymm = symOps.size();
120       for (int s = 1; s < nSymm; s++) {
121         SymOp symOp = symOps.get(s);
122         for (int ii = lb; ii <= ub; ii++) {
123           crystal.applySymRot(inducedDipole[0][ii], inducedDipole[s][ii], symOp);
124           crystal.applySymRot(inducedDipoleCR[0][ii], inducedDipoleCR[s][ii], symOp);
125         }
126       }
127     }
128 
129     @Override
130     public IntegerSchedule schedule() {
131       return IntegerSchedule.fixed();
132     }
133   }
134 }