Constructor for gmx_ekindata_t
[alexxy/gromacs.git] / src / gromacs / mdtypes / group.cpp
index b0c15ca8525b9ce873f998b634cf89f8e1055c17..8e708c737d7be5e818ba77b8ab25f461375ab014 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
 
 #include "group.h"
 
+#include "gromacs/utility/exceptions.h"
+
+gmx_ekindata_t::gmx_ekindata_t(int numTempCoupleGroups, real cos_accel, int numThreads) :
+    ngtc(numTempCoupleGroups),
+    nthreads_(numThreads)
+{
+    tcstat.resize(ngtc);
+    /* Set Berendsen tcoupl lambda's to 1,
+     * so runs without Berendsen coupling are not affected.
+     */
+    for (int i = 0; i < ngtc; i++)
+    {
+        tcstat[i].lambda         = 1.0;
+        tcstat[i].vscale_nhc     = 1.0;
+        tcstat[i].ekinscaleh_nhc = 1.0;
+        tcstat[i].ekinscalef_nhc = 1.0;
+    }
+
+    snew(ekin_work_alloc, nthreads_);
+    snew(ekin_work, nthreads_);
+    snew(dekindl_work, nthreads_);
+
+#pragma omp parallel for num_threads(nthreads_) schedule(static)
+    for (int thread = 0; thread < nthreads_; thread++)
+    {
+        try
+        {
+            constexpr int EKIN_WORK_BUFFER_SIZE = 2;
+            /* Allocate 2 extra elements on both sides, so in single
+             * precision we have
+             * EKIN_WORK_BUFFER_SIZE*DIM*DIM*sizeof(real) = 72/144 bytes
+             * buffer on both sides to avoid cache pollution.
+             */
+            snew(ekin_work_alloc[thread], ngtc + 2 * EKIN_WORK_BUFFER_SIZE);
+            ekin_work[thread] = ekin_work_alloc[thread] + EKIN_WORK_BUFFER_SIZE;
+            /* Nasty hack so we can have the per-thread accumulation
+             * variable for dekindl in the same thread-local cache lines
+             * as the per-thread accumulation tensors for ekin[fh],
+             * because they are accumulated in the same loop. */
+            dekindl_work[thread] = &(ekin_work[thread][ngtc][0][0]);
+        }
+        GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
+    }
+
+    cosacc.cos_accel = cos_accel;
+}
+
 gmx_ekindata_t::~gmx_ekindata_t()
 {
-    for (int i = 0; i < nthreads; i++)
+    for (int i = 0; i < nthreads_; i++)
     {
         sfree(ekin_work_alloc[i]);
     }