Fix bug with DD for dims without PBC
authorBerk Hess <hess@kth.se>
Tue, 6 Nov 2018 14:03:32 +0000 (15:03 +0100)
committerMagnus Lundborg <magnus.lundborg@scilifelab.se>
Thu, 8 Nov 2018 14:00:27 +0000 (15:00 +0100)
When using DD along dimensions without PBC, many pair forces could
be missing. This would not cause silent errors, except when only
running a few steps.

Fixes #2736

Change-Id: Ia256b907e25eef811e1c8f348dc0a78aaddb5610

src/gromacs/domdec/domdec_internal.h
src/gromacs/domdec/partition.cpp

index 83d8fc5709278c02a59df3a9dfe800f423ea10d4..f5754a7f2fd72e8293c384a0ca962821999e4814 100644 (file)
@@ -275,10 +275,11 @@ struct gmx_ddzone_t
     real mch1;    /* The maximum top communicaton height for this zone      */
     real p1_0;    /* The bottom value of the first cell in this zone        */
     real p1_1;    /* The top value of the first cell in this zone           */
+    real dataSet; /* Bool disguised as a real, 1 when the above data has been set. 0 otherwise */
 };
 
 /*! \brief The number of reals in gmx_ddzone_t */
-constexpr int c_ddzoneNumReals = 7;
+constexpr int c_ddzoneNumReals = 8;
 
 template<typename T> class DDBufferAccess;
 
index 7d9e8b6cd9b7aacdd6d863c6d75b1d815641e17f..a81ab75ef2994392e827e36bf80fcf24c6edfdf0 100644 (file)
@@ -149,13 +149,14 @@ static void dd_move_cellx(gmx_domdec_t      *dd,
         gmx_ddzone_t &zp  = (d == 1) ? comm->zone_d1[0] : comm->zone_d2[0][0];
 
         /* Copy the base sizes of the home zone */
-        zp.min0 = cell_ns_x0[dim];
-        zp.max1 = cell_ns_x1[dim];
-        zp.min1 = cell_ns_x1[dim];
-        zp.mch0 = cell_ns_x0[dim];
-        zp.mch1 = cell_ns_x1[dim];
-        zp.p1_0 = cell_ns_x0[dim];
-        zp.p1_1 = cell_ns_x1[dim];
+        zp.min0    = cell_ns_x0[dim];
+        zp.max1    = cell_ns_x1[dim];
+        zp.min1    = cell_ns_x1[dim];
+        zp.mch0    = cell_ns_x0[dim];
+        zp.mch1    = cell_ns_x1[dim];
+        zp.p1_0    = cell_ns_x0[dim];
+        zp.p1_1    = cell_ns_x1[dim];
+        zp.dataSet = 1;
     }
 
     gmx::ArrayRef<DDCellsizesWithDlb> cellsizes = comm->cellsizesWithDlb;
@@ -180,15 +181,18 @@ static void dd_move_cellx(gmx_domdec_t      *dd,
          */
         for (int d1 = d; d1 < dd->ndim-1; d1++)
         {
+            gmx_ddzone_t &buf = buf_s[pos];
+
             /* We invert the order to be able to use the same loop for buf_e */
-            buf_s[pos].min0 = extr_s[d1][1];
-            buf_s[pos].max1 = extr_s[d1][0];
-            buf_s[pos].min1 = extr_s[d1][2];
-            buf_s[pos].mch0 = 0;
-            buf_s[pos].mch1 = 0;
+            buf.min0    = extr_s[d1][1];
+            buf.max1    = extr_s[d1][0];
+            buf.min1    = extr_s[d1][2];
+            buf.mch0    = 0;
+            buf.mch1    = 0;
             /* Store the cell corner of the dimension we communicate along */
-            buf_s[pos].p1_0 = comm->cell_x0[dim];
-            buf_s[pos].p1_1 = 0;
+            buf.p1_0    = comm->cell_x0[dim];
+            buf.p1_1    = 0;
+            buf.dataSet = 1;
             pos++;
         }
 
@@ -356,6 +360,20 @@ static void dd_move_cellx(gmx_domdec_t      *dd,
                     pos++;
                 }
             }
+            else
+            {
+                if (d == 1 || (d == 0 && dd->ndim == 3))
+                {
+                    for (int i = d; i < 2; i++)
+                    {
+                        comm->zone_d2[1 - d][i].dataSet = 0;
+                    }
+                }
+                if (d == 0)
+                {
+                    comm->zone_d1[1].dataSet = 0;
+                }
+            }
         }
     }
 
@@ -364,12 +382,15 @@ static void dd_move_cellx(gmx_domdec_t      *dd,
         int dim = dd->dim[1];
         for (int i = 0; i < 2; i++)
         {
-            if (debug)
+            if (comm->zone_d1[i].dataSet != 0)
             {
-                print_ddzone(debug, 1, i, 0, &comm->zone_d1[i]);
+                if (debug)
+                {
+                    print_ddzone(debug, 1, i, 0, &comm->zone_d1[i]);
+                }
+                cell_ns_x0[dim] = std::min(cell_ns_x0[dim], comm->zone_d1[i].min0);
+                cell_ns_x1[dim] = std::max(cell_ns_x1[dim], comm->zone_d1[i].max1);
             }
-            cell_ns_x0[dim] = std::min(cell_ns_x0[dim], comm->zone_d1[i].min0);
-            cell_ns_x1[dim] = std::max(cell_ns_x1[dim], comm->zone_d1[i].max1);
         }
     }
     if (dd->ndim >= 3)
@@ -379,12 +400,15 @@ static void dd_move_cellx(gmx_domdec_t      *dd,
         {
             for (int j = 0; j < 2; j++)
             {
-                if (debug)
+                if (comm->zone_d2[i][j].dataSet != 0)
                 {
-                    print_ddzone(debug, 2, i, j, &comm->zone_d2[i][j]);
+                    if (debug)
+                    {
+                        print_ddzone(debug, 2, i, j, &comm->zone_d2[i][j]);
+                    }
+                    cell_ns_x0[dim] = std::min(cell_ns_x0[dim], comm->zone_d2[i][j].min0);
+                    cell_ns_x1[dim] = std::max(cell_ns_x1[dim], comm->zone_d2[i][j].max1);
                 }
-                cell_ns_x0[dim] = std::min(cell_ns_x0[dim], comm->zone_d2[i][j].min0);
-                cell_ns_x1[dim] = std::max(cell_ns_x1[dim], comm->zone_d2[i][j].max1);
             }
         }
     }