diff --git a/ipynb-kotlin/ffx.json b/ipynb-kotlin/ffx.json index ab5baef550..776511c3a8 100644 --- a/ipynb-kotlin/ffx.json +++ b/ipynb-kotlin/ffx.json @@ -100,6 +100,7 @@ "jakarta.activation-api-2.1.3.jar", "jakarta.xml.bind-api-4.0.2.jar", "javaparser-core-3.26.4.jar", + "javaparser-core-3.27.0.jar", "javax.annotation-api-1.3.2.jar", "jaxb-core-4.0.3.jar", "jaxb-runtime-4.0.3.jar", diff --git a/modules/algorithms/src/main/groovy/ffx/algorithms/groovy/BAR.groovy b/modules/algorithms/src/main/groovy/ffx/algorithms/groovy/BAR.groovy index 640a75397b..27bf5be910 100644 --- a/modules/algorithms/src/main/groovy/ffx/algorithms/groovy/BAR.groovy +++ b/modules/algorithms/src/main/groovy/ffx/algorithms/groovy/BAR.groovy @@ -112,11 +112,11 @@ class BAR extends AlgorithmsScript { private boolean sortedArc = false @Option(names = ["--ss", "--startSnapshot"], paramLabel = "0", - description = "Start at this snapshot when reading in Tinker BAR files.") + description = "Start at this snapshot when reading in Tinker BAR files (indexed from 0).") private int startingSnapshot = 0 @Option(names = ["--es", "--endSnapshot"], paramLabel = "0", - description = "End at this snapshot when reading in Tinker BAR files.") + description = "End at this snapshot when reading in Tinker BAR files (indexed from 0).") private int endingSnapshot = 0 /** diff --git a/modules/numerics/src/main/java/ffx/numerics/fft/Complex3DParallel.java b/modules/numerics/src/main/java/ffx/numerics/fft/Complex3DParallel.java index 850055ba38..224256da26 100644 --- a/modules/numerics/src/main/java/ffx/numerics/fft/Complex3DParallel.java +++ b/modules/numerics/src/main/java/ffx/numerics/fft/Complex3DParallel.java @@ -331,6 +331,7 @@ public Complex3DParallel(int nX, int nY, int nZ, ParallelTeam parallelTeam, useSIMD = false; } + // Do not pack FFTs by default for now. packFFTs = false; String pack = System.getProperty("fft.packFFTs", Boolean.toString(packFFTs)); try { @@ -360,11 +361,13 @@ public Complex3DParallel(int nX, int nY, int nZ, ParallelTeam parallelTeam, fftZ[i] = new Complex(nZ, dataLayout1D, internalImZ, nY); fftZ[i].setUseSIMD(useSIMD); } - if (!localZTranspose) { - work3D = new double[2 * nX * nY * nZ]; - } else { + + if (localZTranspose) { work3D = null; + } else { + work3D = new double[2 * nX * nY * nZ]; } + fftRegion = new FFTRegion(); ifftRegion = new IFFTRegion(); convRegion = new ConvolutionRegion(); @@ -488,6 +491,7 @@ public void initTiming() { /** * Get the timing string. + * * @return The timing string. */ public String timingString() { @@ -1030,11 +1034,15 @@ private class TransposeLoop extends IntegerForLoop { public void run(final int lb, final int ub) { for (int x = lb; x <= ub; x++) { for (int z = 0; z < nZ; z++) { + int inputOffset = x * nextX + z * nextZ; + int workOffset = x * trNextX + z * trNextZ; for (int y = 0; y < nY; y++) { - double real = input[x * nextX + y * nextY + z * nextZ]; - double imag = input[x * nextX + y * nextY + z * nextZ + im]; - work3D[y * trNextY + z * trNextZ + x * trNextX] = real; - work3D[y * trNextY + z * trNextZ + x * trNextX + internalImZ] = imag; + int inputIndex = inputOffset + y * nextY; + double real = input[inputIndex]; + double imag = input[inputIndex + im]; + int workIndex = workOffset + y * trNextY; + work3D[workIndex] = real; + work3D[workIndex + internalImZ] = imag; } } } @@ -1082,11 +1090,15 @@ private class UnTransposeLoop extends IntegerForLoop { public void run(final int lb, final int ub) { for (int x = 0; x < nX; x++) { for (int y = 0; y < nY; y++) { + int workOffset = x * trNextX + y * trNextY; + int inputOffset = x * nextX + y * nextY; for (int z = lb; z <= ub; z++) { - double real = work3D[y * trNextY + z * trNextZ + x * trNextX]; - double imag = work3D[y * trNextY + z * trNextZ + x * trNextX + internalImZ]; - input[x * nextX + y * nextY + z * nextZ] = real; - input[x * nextX + y * nextY + z * nextZ + im] = imag; + int workIndex = workOffset + z * trNextZ; + double real = work3D[workIndex]; + double imag = work3D[workIndex + internalImZ]; + int inputIndex = inputOffset + z * nextZ; + input[inputIndex] = real; + input[inputIndex + im] = imag; } } } diff --git a/modules/numerics/src/test/java/ffx/numerics/fft/Complex3DParallelTest.java b/modules/numerics/src/test/java/ffx/numerics/fft/Complex3DParallelTest.java index 725ac93293..0804b3ce47 100755 --- a/modules/numerics/src/test/java/ffx/numerics/fft/Complex3DParallelTest.java +++ b/modules/numerics/src/test/java/ffx/numerics/fft/Complex3DParallelTest.java @@ -45,6 +45,7 @@ import java.util.Random; import ffx.utilities.FFXTest; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -101,6 +102,11 @@ public void setUp() { } } + @After + public void after() throws Exception { + parallelTeam.shutdown(); + } + /** Test of convolution method, of class Complex3D. */ @Test public void testConvolution() { diff --git a/modules/numerics/src/test/java/ffx/numerics/fft/Real3DParallelTest.java b/modules/numerics/src/test/java/ffx/numerics/fft/Real3DParallelTest.java index 4dc1d0a533..41f204d718 100755 --- a/modules/numerics/src/test/java/ffx/numerics/fft/Real3DParallelTest.java +++ b/modules/numerics/src/test/java/ffx/numerics/fft/Real3DParallelTest.java @@ -45,6 +45,7 @@ import java.util.Random; import ffx.utilities.FFXTest; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -108,6 +109,11 @@ public void setUp() { } } + @After + public void after() throws Exception { + parallelTeam.shutdown(); + } + /** Test of convolution method, of class Real3DParallel. */ @Test public void testConvolution() { diff --git a/modules/pj/src/main/java/edu/rit/pj/KillRegion.java b/modules/pj/src/main/java/edu/rit/pj/KillRegion.java index 3a5fac60fe..0db008478b 100644 --- a/modules/pj/src/main/java/edu/rit/pj/KillRegion.java +++ b/modules/pj/src/main/java/edu/rit/pj/KillRegion.java @@ -55,9 +55,14 @@ * @author Jacob Litman */ public class KillRegion extends ParallelRegion { + /** {@inheritDoc} */ @Override public void run() throws Exception { - // Does precisely nothing save exist. + // Empty run method. + ParallelTeamThread currentThread = getCurrentThread(); + Thread thread = currentThread.getThread(); + long totalThreads = ParallelTeamThread.totalThreads.getAndDecrement(); + // System.out.printf(" Killing team %s thread %s of %d\n", currentThread.myTeam, thread, totalThreads); } } diff --git a/modules/pj/src/main/java/edu/rit/pj/PJProperties.java b/modules/pj/src/main/java/edu/rit/pj/PJProperties.java index 8bfa33536e..fa746b5fd5 100644 --- a/modules/pj/src/main/java/edu/rit/pj/PJProperties.java +++ b/modules/pj/src/main/java/edu/rit/pj/PJProperties.java @@ -233,6 +233,26 @@ public static int getPjNt() { return k; } + /** + * Determine whether a {@linkplain ParallelTeam} should use virtual threads. + *
+ * If the "pj.vt" Java system property is true, then virtual threads
+ * will be used. If the property is false or not specified, then the
+ * program will use platform threads.
+ *
+ * The default is false, meaning that the program will use platform threads. + *
+ * @return true if the program should use virtual threads, false otherwise.
+ */
+ public static boolean getPjVt() {
+ String pjVtProperty = System.getProperty("pj.vt");
+ if (pjVtProperty != null) {
+ return Boolean.parseBoolean(pjVtProperty);
+ } else {
+ return false; // Default is false
+ }
+ }
+
/**
* Determine the schedule for a parallel loop in an SMP parallel program.
* This is the schedule that will be used if the parallel for loop has a
diff --git a/modules/pj/src/main/java/edu/rit/pj/ParallelConstruct.java b/modules/pj/src/main/java/edu/rit/pj/ParallelConstruct.java
index a9df6fb78c..24fb58297c 100644
--- a/modules/pj/src/main/java/edu/rit/pj/ParallelConstruct.java
+++ b/modules/pj/src/main/java/edu/rit/pj/ParallelConstruct.java
@@ -148,16 +148,13 @@ ParallelTeamThread getCurrentThread() {
if (myTeam == null) {
throw new IllegalStateException("ParallelConstruct.getCurrentThread(): No parallel team executing");
}
- try {
- ParallelTeamThread current = (ParallelTeamThread) Thread.currentThread();
- if (current.myTeam != this.myTeam) {
- throw new IllegalStateException("ParallelConstruct.getCurrentThread(): Current thread is not executing this parallel construct");
+ Thread currentThread = Thread.currentThread();
+ for (ParallelTeamThread teamThread : myTeam.myThread) {
+ if (teamThread.getThread() == currentThread) {
+ return teamThread;
}
- return current;
- } catch (ClassCastException exc) {
- throw new IllegalStateException("ParallelConstruct.getCurrentThread(): Current thread is not a parallel team thread",
- exc);
}
+ throw new IllegalStateException("ParallelConstruct.getCurrentThread(): Current thread is not executing this parallel construct");
}
-}
+}
\ No newline at end of file
diff --git a/modules/pj/src/main/java/edu/rit/pj/ParallelTeam.java b/modules/pj/src/main/java/edu/rit/pj/ParallelTeam.java
index 548e92fc57..53cb3d5939 100644
--- a/modules/pj/src/main/java/edu/rit/pj/ParallelTeam.java
+++ b/modules/pj/src/main/java/edu/rit/pj/ParallelTeam.java
@@ -162,7 +162,7 @@ public final void execute(ParallelRegion theRegion)
// Record parallel region.
myRegion = theRegion;
- myExceptionMap = new ConcurrentHashMap Set polarizationScale to L for part 1. Set polarizationScale to (1-L) for parts 2 & 3.
*/
private double polarizationScale = 1.0;
+
// *************************************************************************
// Mutable Particle Mesh Ewald constants.
private double aewald;
diff --git a/modules/potential/src/main/java/ffx/potential/nonbonded/pme/ReciprocalEnergyRegion.java b/modules/potential/src/main/java/ffx/potential/nonbonded/pme/ReciprocalEnergyRegion.java
index b0e46152f2..9cf2d3375c 100644
--- a/modules/potential/src/main/java/ffx/potential/nonbonded/pme/ReciprocalEnergyRegion.java
+++ b/modules/potential/src/main/java/ffx/potential/nonbonded/pme/ReciprocalEnergyRegion.java
@@ -57,6 +57,8 @@
import static ffx.potential.parameters.MultipoleType.t201;
import static ffx.potential.parameters.MultipoleType.t210;
import static ffx.potential.parameters.MultipoleType.t300;
+import static java.lang.Math.PI;
+import static java.lang.String.format;
import static org.apache.commons.math3.util.FastMath.sqrt;
import edu.rit.pj.IntegerForLoop;
@@ -83,9 +85,10 @@ public class ReciprocalEnergyRegion extends ParallelRegion {
private static final Logger logger = Logger.getLogger(ReciprocalEnergyRegion.class.getName());
- private static final double SQRT_PI = sqrt(Math.PI);
+ private static final double SQRT_PI = sqrt(PI);
private static final int tensorCount = MultipoleUtilities.tensorCount(3);
private final double electric;
+ private final double aewald;
private final double aewald1;
private final double aewald2;
private final double aewald3;
@@ -110,6 +113,7 @@ public class ReciprocalEnergyRegion extends ParallelRegion {
private double[][] fracMultipolePhi;
private double[][] fracInducedDipolePhi;
private double[][] fracInducedDipolePhiCR;
+ private double chargeCorrectionEnergy;
private double permanentSelfEnergy;
private double permanentReciprocalEnergy;
/** An ordered array of atoms in the system. */
@@ -182,8 +186,8 @@ public ReciprocalEnergyRegion(int nt, double aewald, double electric) {
inducedDipoleSelfEnergy = new SharedDouble();
inducedDipoleRecipEnergy = new SharedDouble();
maxThreads = nt;
-
this.electric = electric;
+ this.aewald = aewald;
aewald1 = -electric * aewald / SQRT_PI;
aewald2 = 2.0 * aewald * aewald;
aewald3 = -2.0 / 3.0 * electric * aewald * aewald * aewald / SQRT_PI;
@@ -215,10 +219,40 @@ public void finish() {
*/
permanentSelfEnergy = 0.0;
permanentReciprocalEnergy = 0.0;
+ double totalCharge = 0.0;
for (int i = 0; i < maxThreads; i++) {
+ totalCharge += permanentReciprocalEnergyLoop[i].totalCharge;
permanentSelfEnergy += permanentReciprocalEnergyLoop[i].eSelf;
permanentReciprocalEnergy += permanentReciprocalEnergyLoop[i].eRecip;
}
+
+ if (totalCharge == 0.0 || (esvTerm && !extendedSystem.useTotalChargeCorrection)) {
+ chargeCorrectionEnergy = 0.0;
+ } else {
+ Crystal unitCell = crystal.getUnitCell();
+ int nSymm = unitCell.getNumSymOps();
+ // Compute the total charge for the unit cell from the asymmetric unit total.
+ totalCharge = totalCharge * nSymm;
+ double denom = unitCell.volume * aewald * aewald;
+ chargeCorrectionEnergy = -0.5 * electric * PI * (totalCharge * totalCharge) / denom;
+ // Normalize the unit cell correction to the asymmetric unit.
+ chargeCorrectionEnergy = chargeCorrectionEnergy / nSymm;
+ if (lambdaTerm) {
+ shareddEdLambda.addAndGet(chargeCorrectionEnergy * dlPowPerm * dEdLSign);
+ sharedd2EdLambda2.addAndGet(chargeCorrectionEnergy * d2lPowPerm * dEdLSign);
+ }
+ if (esvTerm){
+ for(int i=0; i