Implemented LJ-PME nbnxn kernels
[alexxy/gromacs.git] / src / gromacs / mdlib / nbnxn_kernels / simd_2xnn / nbnxn_kernel_simd_2xnn.c
index 4bf21fa8249e965e3d1a580e45d5dfcef1ff9d8c..d8ec1d2edc4c3a863b8a9667ac4ea5c9cc8485eb 100644 (file)
 /*! \brief Kinds of electrostatic treatments in SIMD Verlet kernels
  */
 enum {
-    coultRF, coultTAB, coultTAB_TWIN, coultEWALD, coultEWALD_TWIN, coultNR
+    coulktRF, coulktTAB, coulktTAB_TWIN, coulktEWALD, coulktEWALD_TWIN, coulktNR
+};
+
+/*! \brief Kinds of Van der Waals treatments in SIMD Verlet kernels
+ */
+enum {
+    vdwktLJCUT_COMBGEOM, vdwktLJCUT_COMBLB, vdwktLJCUT_COMBNONE, vdwktLJFORCESWITCH, vdwktLJPOTSWITCH, vdwktLJEWALDCOMBGEOM, vdwktNR
 };
 
 /* Declare and define the kernel function pointer lookup tables.
  * The minor index of the array goes over both the LJ combination rules,
- * which is only supported by plain cut-off, and the LJ switch functions.
+ * which is only supported by plain cut-off, and the LJ switch/PME functions.
  */
-static p_nbk_func_noener p_nbk_noener[coultNR][ljcrNR+2] =
+static p_nbk_func_noener p_nbk_noener[coulktNR][vdwktNR] =
 {
     {
         nbnxn_kernel_ElecRF_VdwLJCombGeom_F_2xnn,
@@ -79,6 +85,7 @@ static p_nbk_func_noener p_nbk_noener[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecRF_VdwLJ_F_2xnn,
         nbnxn_kernel_ElecRF_VdwLJFSw_F_2xnn,
         nbnxn_kernel_ElecRF_VdwLJPSw_F_2xnn,
+        nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_2xnn,
     },
     {
         nbnxn_kernel_ElecQSTab_VdwLJCombGeom_F_2xnn,
@@ -86,6 +93,7 @@ static p_nbk_func_noener p_nbk_noener[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecQSTab_VdwLJ_F_2xnn,
         nbnxn_kernel_ElecQSTab_VdwLJFSw_F_2xnn,
         nbnxn_kernel_ElecQSTab_VdwLJPSw_F_2xnn,
+        nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_F_2xnn,
     },
     {
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_2xnn,
@@ -93,6 +101,7 @@ static p_nbk_func_noener p_nbk_noener[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_2xnn,
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJFSw_F_2xnn,
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJPSw_F_2xnn,
+        nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_2xnn,
     },
     {
         nbnxn_kernel_ElecEw_VdwLJCombGeom_F_2xnn,
@@ -100,6 +109,7 @@ static p_nbk_func_noener p_nbk_noener[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecEw_VdwLJ_F_2xnn,
         nbnxn_kernel_ElecEw_VdwLJFSw_F_2xnn,
         nbnxn_kernel_ElecEw_VdwLJPSw_F_2xnn,
+        nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_2xnn,
     },
     {
         nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_2xnn,
@@ -107,10 +117,11 @@ static p_nbk_func_noener p_nbk_noener[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_2xnn,
         nbnxn_kernel_ElecEwTwinCut_VdwLJFSw_F_2xnn,
         nbnxn_kernel_ElecEwTwinCut_VdwLJPSw_F_2xnn,
+        nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_2xnn,
     },
 };
 
-static p_nbk_func_ener p_nbk_ener[coultNR][ljcrNR+2] =
+static p_nbk_func_ener p_nbk_ener[coulktNR][vdwktNR] =
 {
     {
         nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_2xnn,
@@ -118,6 +129,7 @@ static p_nbk_func_ener p_nbk_ener[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecRF_VdwLJ_VF_2xnn,
         nbnxn_kernel_ElecRF_VdwLJFSw_VF_2xnn,
         nbnxn_kernel_ElecRF_VdwLJPSw_VF_2xnn,
+        nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_2xnn,
     },
     {
         nbnxn_kernel_ElecQSTab_VdwLJCombGeom_VF_2xnn,
@@ -125,6 +137,7 @@ static p_nbk_func_ener p_nbk_ener[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecQSTab_VdwLJ_VF_2xnn,
         nbnxn_kernel_ElecQSTab_VdwLJFSw_VF_2xnn,
         nbnxn_kernel_ElecQSTab_VdwLJPSw_VF_2xnn,
+        nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VF_2xnn,
     },
     {
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_2xnn,
@@ -132,6 +145,7 @@ static p_nbk_func_ener p_nbk_ener[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_2xnn,
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_2xnn,
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_2xnn,
+        nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_2xnn,
     },
     {
         nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_2xnn,
@@ -139,6 +153,7 @@ static p_nbk_func_ener p_nbk_ener[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecEw_VdwLJ_VF_2xnn,
         nbnxn_kernel_ElecEw_VdwLJFSw_VF_2xnn,
         nbnxn_kernel_ElecEw_VdwLJPSw_VF_2xnn,
+        nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_2xnn,
     },
     {
         nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_2xnn,
@@ -146,10 +161,11 @@ static p_nbk_func_ener p_nbk_ener[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_2xnn,
         nbnxn_kernel_ElecEwTwinCut_VdwLJFSw_VF_2xnn,
         nbnxn_kernel_ElecEwTwinCut_VdwLJPSw_VF_2xnn,
+        nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_2xnn,
     },
 };
 
-static p_nbk_func_ener p_nbk_energrp[coultNR][ljcrNR+2] =
+static p_nbk_func_ener p_nbk_energrp[coulktNR][vdwktNR] =
 {
     {
         nbnxn_kernel_ElecRF_VdwLJCombGeom_VgrpF_2xnn,
@@ -157,6 +173,7 @@ static p_nbk_func_ener p_nbk_energrp[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecRF_VdwLJ_VgrpF_2xnn,
         nbnxn_kernel_ElecRF_VdwLJFSw_VgrpF_2xnn,
         nbnxn_kernel_ElecRF_VdwLJPSw_VgrpF_2xnn,
+        nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_2xnn,
     },
     {
         nbnxn_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_2xnn,
@@ -164,6 +181,7 @@ static p_nbk_func_ener p_nbk_energrp[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_2xnn,
         nbnxn_kernel_ElecQSTab_VdwLJFSw_VgrpF_2xnn,
         nbnxn_kernel_ElecQSTab_VdwLJPSw_VgrpF_2xnn,
+        nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_2xnn,
     },
     {
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_2xnn,
@@ -171,6 +189,7 @@ static p_nbk_func_ener p_nbk_energrp[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_2xnn,
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_2xnn,
         nbnxn_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_2xnn,
+        nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_2xnn,
     },
     {
         nbnxn_kernel_ElecEw_VdwLJCombGeom_VgrpF_2xnn,
@@ -178,6 +197,7 @@ static p_nbk_func_ener p_nbk_energrp[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecEw_VdwLJ_VgrpF_2xnn,
         nbnxn_kernel_ElecEw_VdwLJFSw_VgrpF_2xnn,
         nbnxn_kernel_ElecEw_VdwLJPSw_VgrpF_2xnn,
+        nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_2xnn,
     },
     {
         nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_2xnn,
@@ -185,6 +205,7 @@ static p_nbk_func_ener p_nbk_energrp[coultNR][ljcrNR+2] =
         nbnxn_kernel_ElecEwTwinCut_VdwLJ_VgrpF_2xnn,
         nbnxn_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_2xnn,
         nbnxn_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_2xnn,
+        nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_2xnn,
     },
 };
 
@@ -250,7 +271,7 @@ nbnxn_kernel_simd_2xnn(nbnxn_pairlist_set_t      gmx_unused *nbl_list,
 {
     int                nnbl;
     nbnxn_pairlist_t **nbl;
-    int                coult, ljtreatment = 0;
+    int                coulkt, vdwkt = 0;
     int                nb;
 
     nnbl = nbl_list->nnbl;
@@ -258,7 +279,7 @@ nbnxn_kernel_simd_2xnn(nbnxn_pairlist_set_t      gmx_unused *nbl_list,
 
     if (EEL_RF(ic->eeltype) || ic->eeltype == eelCUT)
     {
-        coult = coultRF;
+        coulkt = coulktRF;
     }
     else
     {
@@ -266,41 +287,61 @@ nbnxn_kernel_simd_2xnn(nbnxn_pairlist_set_t      gmx_unused *nbl_list,
         {
             if (ic->rcoulomb == ic->rvdw)
             {
-                coult = coultTAB;
+                coulkt = coulktTAB;
             }
             else
             {
-                coult = coultTAB_TWIN;
+                coulkt = coulktTAB_TWIN;
             }
         }
         else
         {
             if (ic->rcoulomb == ic->rvdw)
             {
-                coult = coultEWALD;
+                coulkt = coulktEWALD;
             }
             else
             {
-                coult = coultEWALD_TWIN;
+                coulkt = coulktEWALD_TWIN;
             }
         }
     }
 
-    switch (ic->vdw_modifier)
+    if (ic->vdwtype == evdwCUT)
+    {
+        switch (ic->vdw_modifier)
+        {
+            case eintmodNONE:
+            case eintmodPOTSHIFT:
+                switch (nbat->comb_rule)
+                {
+                    case ljcrGEOM: vdwkt = vdwktLJCUT_COMBGEOM; break;
+                    case ljcrLB:   vdwkt = vdwktLJCUT_COMBLB;   break;
+                    case ljcrNONE: vdwkt = vdwktLJCUT_COMBNONE; break;
+                    default:       gmx_incons("Unknown combination rule");
+                }
+                break;
+            case eintmodFORCESWITCH:
+                vdwkt = vdwktLJFORCESWITCH;
+                break;
+            case eintmodPOTSWITCH:
+                vdwkt = vdwktLJPOTSWITCH;
+                break;
+            default:
+                gmx_incons("Unsupported VdW interaction modifier");
+        }
+    }
+    else if (ic->vdwtype == evdwPME)
+    {
+        if (ic->ljpme_comb_rule == eljpmeLB)
+        {
+            gmx_incons("The nbnxn SIMD kernels don't suport LJ-PME with LB");
+        }
+        vdwkt = vdwktLJEWALDCOMBGEOM;
+    }
+    else
     {
-        case eintmodNONE:
-        case eintmodPOTSHIFT:
-            ljtreatment = nbat->comb_rule;
-            break;
-        /* Switch functions follow after cut-off combination rule kernels */
-        case eintmodFORCESWITCH:
-            ljtreatment = ljcrNR;
-            break;
-        case eintmodPOTSWITCH:
-            ljtreatment = ljcrNR + 1;
-            break;
-        default:
-            gmx_incons("Unsupported VdW interaction modifier");
+        gmx_incons("Unsupported VdW interaction type");
     }
 
 #pragma omp parallel for schedule(static) num_threads(gmx_omp_nthreads_get(emntNonbonded))
@@ -333,11 +374,11 @@ nbnxn_kernel_simd_2xnn(nbnxn_pairlist_set_t      gmx_unused *nbl_list,
         if (!(force_flags & GMX_FORCE_ENERGY))
         {
             /* Don't calculate energies */
-            p_nbk_noener[coult][ljtreatment](nbl[nb], nbat,
-                                             ic,
-                                             shift_vec,
-                                             out->f,
-                                             fshift_p);
+            p_nbk_noener[coulkt][vdwkt](nbl[nb], nbat,
+                                        ic,
+                                        shift_vec,
+                                        out->f,
+                                        fshift_p);
         }
         else if (out->nV == 1)
         {
@@ -345,13 +386,13 @@ nbnxn_kernel_simd_2xnn(nbnxn_pairlist_set_t      gmx_unused *nbl_list,
             out->Vvdw[0] = 0;
             out->Vc[0]   = 0;
 
-            p_nbk_ener[coult][ljtreatment](nbl[nb], nbat,
-                                           ic,
-                                           shift_vec,
-                                           out->f,
-                                           fshift_p,
-                                           out->Vvdw,
-                                           out->Vc);
+            p_nbk_ener[coulkt][vdwkt](nbl[nb], nbat,
+                                      ic,
+                                      shift_vec,
+                                      out->f,
+                                      fshift_p,
+                                      out->Vvdw,
+                                      out->Vc);
         }
         else
         {
@@ -367,13 +408,13 @@ nbnxn_kernel_simd_2xnn(nbnxn_pairlist_set_t      gmx_unused *nbl_list,
                 out->VSc[i] = 0;
             }
 
-            p_nbk_energrp[coult][ljtreatment](nbl[nb], nbat,
-                                              ic,
-                                              shift_vec,
-                                              out->f,
-                                              fshift_p,
-                                              out->VSvdw,
-                                              out->VSc);
+            p_nbk_energrp[coulkt][vdwkt](nbl[nb], nbat,
+                                         ic,
+                                         shift_vec,
+                                         out->f,
+                                         fshift_p,
+                                         out->VSvdw,
+                                         out->VSc);
 
             reduce_group_energies(nbat->nenergrp, nbat->neg_2log,
                                   out->VSvdw, out->VSc,