NAMD
ComputeNonbondedUtil.C
Go to the documentation of this file.
1 
7 /*
8  Common operations for ComputeNonbonded classes
9 */
10 
11 #ifdef WIN32
12 extern "C" {
13  double erfc(double);
14 }
15 #endif
16 
17 #include "InfoStream.h"
18 #include "ComputeNonbondedUtil.h"
19 #include "SimParameters.h"
20 #include "Node.h"
21 #include "Molecule.h"
22 #include "LJTable.h"
23 #include "ReductionMgr.h"
24 #include "Parameters.h"
25 #include "MsmMacros.h"
26 #include <stdio.h>
27 
28 #ifdef NAMD_MIC
29  extern void send_build_mic_force_table();
30 #endif
31 
59 #if defined(NAMD_MIC)
60  BigReal* ComputeNonbondedUtil::mic_table_base_ptr;
61  int ComputeNonbondedUtil::mic_table_n;
62  int ComputeNonbondedUtil::mic_table_n_16;
63 #endif
64 #ifdef NAMD_AVXTILES
65 int ComputeNonbondedUtil::avxTilesMode;
66 float* ComputeNonbondedUtil::avx_tiles_eps4_sigma = 0;
67 float* ComputeNonbondedUtil::avx_tiles_eps4_sigma_14 = 0;
68 #endif
69 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
70 float* ComputeNonbondedUtil::knl_table_alloc;
71 float* ComputeNonbondedUtil::knl_fast_ener_table;
72 float* ComputeNonbondedUtil::knl_fast_grad_table;
73 float* ComputeNonbondedUtil::knl_scor_ener_table;
74 float* ComputeNonbondedUtil::knl_scor_grad_table;
75 float* ComputeNonbondedUtil::knl_slow_ener_table;
76 float* ComputeNonbondedUtil::knl_slow_grad_table;
77 float* ComputeNonbondedUtil::knl_excl_ener_table;
78 float* ComputeNonbondedUtil::knl_excl_grad_table;
79 #ifdef NAMD_KNL
80 float* ComputeNonbondedUtil::knl_corr_ener_table;
81 float* ComputeNonbondedUtil::knl_corr_grad_table;
82 #endif
83 #endif
115 // BigReal ComputeNonbondedUtil::d0;
116 // fepb
123 //fepe
127 
129 
132 
138 
140 
142 
146 
148 
149 // Ported by JLai -- JE - Go
152 int ComputeNonbondedUtil::goMethod; //6.3.11
153 // End of port -- JLai
154 
159 
164 
169 
174 
179 
184 
189 
190 // define splitting function
191 #define SPLIT_NONE 1
192 #define SPLIT_SHIFT 2
193 #define SPLIT_C1 3
194 #define SPLIT_XPLOR 4
195 #define SPLIT_C2 5
196 #define SPLIT_MARTINI 6
197 
199 {
202  reduction->item(REDUCTION_ELECT_ENERGY) += data[electEnergyIndex];
204  reduction->item(REDUCTION_LJ_ENERGY) += data[vdwEnergyIndex];
205  reduction->item(REDUCTION_LJ_ENERGY_SLOW) += data[fullVdwEnergyIndex];
206  // Ported by JLai
207  reduction->item(REDUCTION_GRO_LJ_ENERGY) += data[groLJEnergyIndex];
211  // End of port -- JLai
212 //fepb
213  reduction->item(REDUCTION_ELECT_ENERGY_F) += data[electEnergyIndex_s];
215  reduction->item(REDUCTION_LJ_ENERGY_F) += data[vdwEnergyIndex_s];
216 
223 //fepe
224  ADD_TENSOR(reduction,REDUCTION_VIRIAL_NBOND,data,virialIndex);
225  ADD_TENSOR(reduction,REDUCTION_VIRIAL_SLOW,data,fullElectVirialIndex);
226  ADD_VECTOR(reduction,REDUCTION_PAIR_VDW_FORCE,data,pairVDWForceIndex);
227  ADD_VECTOR(reduction,REDUCTION_PAIR_ELECT_FORCE,data,pairElectForceIndex);
228  reduction->item(REDUCTION_COMPUTE_CHECKSUM) += 1.;
229 }
230 
232  SubmitReduction *reduction)
233 {
234  if (!reduction) return;
235  int numAtomTypes = pressureProfileAtomTypes;
236  // For ease of calculation we stored interactions between types
237  // i and j in (ni+j). For efficiency now we coalesce the
238  // cross interactions so that just i<=j are stored.
239  const int arraysize = 3*pressureProfileSlabs;
240  size_t nelems = arraysize*(numAtomTypes*(numAtomTypes+1))/2;
241  BigReal *arr = new BigReal[nelems];
242  memset(arr, 0, nelems*sizeof(BigReal));
243 
244  int i, j;
245  for (i=0; i<numAtomTypes; i++) {
246  for (j=0; j<numAtomTypes; j++) {
247  int ii=i;
248  int jj=j;
249  if (ii > jj) { int tmp=ii; ii=jj; jj=tmp; }
250  const int reductionOffset = (ii*numAtomTypes - (ii*(ii+1))/2 + jj)*arraysize;
251  for (int k=0; k<arraysize; k++) {
252  arr[reductionOffset+k] += data[k];
253  }
254  data += arraysize;
255  }
256  }
257  // copy into reduction
258  reduction->add(nelems, arr);
259  delete [] arr;
260 }
261 
263  NAMD_bug("Tried to call missing nonbonded compute routine.");
264 }
265 
267 {
268  if ( CkMyRank() ) return;
269 
270  // These defaults die cleanly if nothing appropriate is assigned.
299 
301  Parameters * params = Node::Object()->parameters;
302 
303  table_ener = params->table_ener;
304  rowsize = params->rowsize;
305  columnsize = params->columnsize;
306 
307  commOnly = simParams->commOnly;
308  fixedAtomsOn = ( simParams->fixedAtomsOn && ! simParams->fixedAtomsForces );
309 
310  qmForcesOn = simParams->qmForcesOn ;
311 
312  cutoff = simParams->cutoff;
314  cutoff2_f = cutoff2;
315 
316 //fepb
317  alchFepOn = simParams->alchFepOn;
318  alchThermIntOn = simParams->alchThermIntOn;
319  alchWCAOn = simParams->alchWCAOn;
320  alchDecouple = simParams->alchDecouple;
321 
322  lesOn = simParams->lesOn;
323  lesScaling = lesFactor = 0;
324 
325  Bool tabulatedEnergies = simParams->tabulatedEnergies;
326  alchVdwShiftCoeff = simParams->alchVdwShiftCoeff;
327  vdwForceSwitching = simParams->vdwForceSwitching;
328 
329  delete [] lambda_table;
330  lambda_table = 0;
331 
332  pairInteractionOn = simParams->pairInteractionOn;
333  pairInteractionSelf = simParams->pairInteractionSelf;
334  pressureProfileOn = simParams->pressureProfileOn;
335 
336  // Ported by JLai -- Original JE - Go
337  goGroPair = simParams->goGroPair;
338  goForcesOn = simParams->goForcesOn;
339  goMethod = simParams->goMethod;
340  // End of port
341 
342  accelMDOn = simParams->accelMDOn;
343 
344  drudeNbthole = simParams->drudeOn && (simParams->drudeNbtholeCut > 0.0);
345 
346  if ( drudeNbthole ) {
347 // #if defined(NAMD_CUDA) || defined(NAMD_HIP)
348 // NAMD_die("drudeNbthole is not supported in CUDA version");
349 // #endif
350  if ( lesOn )
351  NAMD_die("drudeNbthole is not supported with locally enhanced sampling");
352  if ( pairInteractionOn )
353  NAMD_die("drudeNbthole is not supported with pair interaction calculation");
354  if ( pressureProfileOn )
355  NAMD_die("drudeNbthole is not supported with pressure profile calculation");
356  }
357 
358  if ( alchFepOn ) {
375  } else if ( alchThermIntOn ) {
392  } else if ( lesOn ) {
393 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
394  NAMD_die("Locally enhanced sampling is not supported in CUDA version");
395 #endif
396  lesFactor = simParams->lesFactor;
397  lesScaling = 1.0 / (double)lesFactor;
398  lambda_table = new BigReal[(lesFactor+1)*(lesFactor+1)];
399  for ( int ip=0; ip<=lesFactor; ++ip ) {
400  for ( int jp=0; jp<=lesFactor; ++jp ) {
401  BigReal lambda_pair = 1.0;
402  if (ip || jp ) {
403  if (ip && jp && ip != jp) {
404  lambda_pair = 0.0;
405  } else {
406  lambda_pair = lesScaling;
407  }
408  }
409  lambda_table[(lesFactor+1)*ip+jp] = lambda_pair;
410  }
411  }
428  } else if ( pressureProfileOn) {
429 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
430  NAMD_die("Pressure profile calculation is not supported in CUDA version");
431 #endif
432  pressureProfileSlabs = simParams->pressureProfileSlabs;
433  pressureProfileAtomTypes = simParams->pressureProfileAtomTypes;
434 
451  } else if ( pairInteractionOn ) {
452 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
453  NAMD_die("Pair interaction calculation is not supported in CUDA version");
454 #endif
461  } else if ( tabulatedEnergies ) {
462 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
463  NAMD_die("Tabulated energies is not supported in CUDA version");
464 #endif
481  } else if ( goForcesOn ) {
482 #ifdef NAMD_CUDA
483  NAMD_die("Go forces is not supported in CUDA version");
484 #endif
501  } else {
530  }
531 
532 //fepe
533 
534  dielectric_1 = 1.0/simParams->dielectric;
535  if ( simParams->soluteScalingOn ) {
536  delete ljTable;
537  ljTable = 0;
538  }
539  if ( ! ljTable ) ljTable = new LJTable;
541  scaling = simParams->nonbondedScaling;
542  if ( simParams->exclude == SCALED14 )
543  {
544  scale14 = simParams->scale14;
545  }
546  else
547  {
548  scale14 = 1.;
549  }
550  if ( simParams->switchingActive )
551  {
552  switchOn = simParams->switchingDist;
553  switchOn_1 = 1.0/switchOn;
554  // d0 = 1.0/(cutoff-switchOn);
556  c0 = 1.0/(cutoff2-switchOn2);
557 
558  if ( simParams->vdwForceSwitching ) {
559  double switchOn3 = switchOn * switchOn2;
560  double cutoff3 = cutoff * cutoff2;
561  double switchOn6 = switchOn3 * switchOn3;
562  double cutoff6 = cutoff3 * cutoff3;
563  v_vdwa_f = v_vdwa = -1. / ( switchOn6 * cutoff6 );
564  v_vdwb_f = v_vdwb = -1. / ( switchOn3 * cutoff3 );
565  k_vdwa_f = k_vdwa = cutoff6 / ( cutoff6 - switchOn6 );
566  k_vdwb_f = k_vdwb = cutoff3 / ( cutoff3 - switchOn3 );
567  cutoff_3_f = cutoff_3 = 1. / cutoff3;
568  cutoff_6_f = cutoff_6 = 1. / cutoff6;
569 
570  } else if ( simParams->martiniSwitching ) { // switching fxn for Martini RBCG
571 
572  BigReal p6 = 6;
573  BigReal A6 = p6 * ((p6+1)*switchOn-(p6+4)*cutoff)/(pow(cutoff,p6+2)*pow(cutoff-switchOn,2));
574  BigReal B6 = -p6 * ((p6+1)*switchOn-(p6+3)*cutoff)/(pow(cutoff,p6+2)*pow(cutoff-switchOn,3));
575  BigReal C6 = 1.0/pow(cutoff,p6)-A6/3.0*pow(cutoff-switchOn,3)-B6/4.0*pow(cutoff-switchOn,4);
576 
577  BigReal p12 = 12;
578  BigReal A12 = p12 * ((p12+1)*switchOn-(p12+4)*cutoff)/(pow(cutoff,p12+2)*pow(cutoff-switchOn,2));
579  BigReal B12 = -p12 * ((p12+1)*switchOn-(p12+3)*cutoff)/(pow(cutoff,p12+2)*pow(cutoff-switchOn,3));
580  BigReal C12 = 1.0/pow(cutoff,p12)-A12/3.0*pow(cutoff-switchOn,3)-B12/4.0*pow(cutoff-switchOn,4);
581 
582  A6_f = A6; B6_f = B6; C6_f = C6;
583  A12_f = A12; B12_f = B12; C12_f = C12;
585 
586  }
587 
588  }
589  else
590  {
591  switchOn = cutoff;
592  switchOn_1 = 1.0/switchOn;
593  // d0 = 0.; // avoid division by zero
595  c0 = 0.; // avoid division by zero
596  }
597  c1 = c0*c0*c0;
598  c3 = 3.0 * (cutoff2 - switchOn2);
599  c5 = 0;
600  c6 = 0;
601  c7 = 0;
602  c8 = 0;
603 
604  const int PMEOn = simParams->PMEOn;
605  const int LJPMEOn = simParams->LJPMEOn;
606  const int MSMOn = simParams->MSMOn;
607  const int MSMSplit = simParams->MSMSplit;
608 
609  if ( PMEOn ) {
610  ewaldcof = simParams->PMEEwaldCoefficient;
611  BigReal TwoBySqrtPi = 1.12837916709551;
612  pi_ewaldcof = TwoBySqrtPi * ewaldcof;
613  }
614  if ( LJPMEOn ) {
615  LJewaldcof = simParams->LJPMEEwaldCoefficient;
616  }
617 
618  int splitType = SPLIT_NONE;
619  if ( simParams->switchingActive ) splitType = SPLIT_SHIFT;
620  if ( simParams->martiniSwitching ) splitType = SPLIT_MARTINI;
621  if ( simParams->fullDirectOn || simParams->FMAOn || PMEOn || MSMOn ||
622  simParams->FMMOn ) {
623  switch ( simParams->longSplitting ) {
624  case C2:
625  splitType = SPLIT_C2;
626  break;
627 
628  case C1:
629  splitType = SPLIT_C1;
630  break;
631 
632  case XPLOR:
633  NAMD_die("Sorry, XPLOR splitting not supported.");
634  break;
635 
636  case SHARP:
637  NAMD_die("Sorry, SHARP splitting not supported.");
638  break;
639 
640  default:
641  NAMD_die("Unknown splitting type found!");
642 
643  }
644  }
645 
646  BigReal r2_tol = 0.1;
647 
648  r2_delta = 1.0;
649  r2_delta_exp = 0;
650  while ( r2_delta > r2_tol ) { r2_delta /= 2.0; r2_delta_exp += 1; }
651  r2_delta_1 = 1.0 / r2_delta;
652 
653  if ( ! CkMyPe() ) {
654  iout << iINFO << "NONBONDED TABLE R-SQUARED SPACING: " <<
655  r2_delta << "\n" << endi;
656  }
657 
658  BigReal r2_tmp = 1.0;
659  int cutoff2_exp = 0;
660  while ( (cutoff2 + r2_delta) > r2_tmp ) { r2_tmp *= 2.0; cutoff2_exp += 1; }
661 
662  int i;
663  int n = (r2_delta_exp + cutoff2_exp) * 64 + 1;
664  table_length = n;
665  #if defined(NAMD_MIC)
666  int n_16 = (n + 15) & (~15);
667  #endif
668 
669  if ( ! CkMyPe() ) {
670  iout << iINFO << "NONBONDED TABLE SIZE: " <<
671  n << " POINTS\n" << endi;
672  }
673 
674  if ( table_alloc ) delete [] table_alloc;
675  #if defined(NAMD_MIC)
676  table_alloc = new BigReal[61*n_16+16];
677  BigReal *table_align = table_alloc;
678  while ( ((long)table_align) % 128 ) ++table_align;
679  mic_table_base_ptr = table_align;
680  mic_table_n = n;
681  mic_table_n_16 = n_16;
682  table_noshort = table_align;
683  table_short = table_align + 16*n_16;
684  slow_table = table_align + 32*n_16;
685  fast_table = table_align + 36*n_16;
686  scor_table = table_align + 40*n_16;
687  corr_table = table_align + 44*n_16;
688  full_table = table_align + 48*n_16;
689  vdwa_table = table_align + 52*n_16;
690  vdwb_table = table_align + 56*n_16;
691  r2_table = table_align + 60*n_16;
692  #else
693  table_alloc = new BigReal[61*n+16];
694  BigReal *table_align = table_alloc;
695  while ( ((long)table_align) % 128 ) ++table_align;
696  table_noshort = table_align;
697  table_short = table_align + 16*n;
698  slow_table = table_align + 32*n;
699  fast_table = table_align + 36*n;
700  scor_table = table_align + 40*n;
701  corr_table = table_align + 44*n;
702  full_table = table_align + 48*n;
703  vdwa_table = table_align + 52*n;
704  vdwb_table = table_align + 56*n;
705  r2_table = table_align + 60*n;
706  #endif
707  BigReal *fast_i = fast_table + 4;
708  BigReal *scor_i = scor_table + 4;
709  BigReal *slow_i = slow_table + 4;
710  BigReal *vdwa_i = vdwa_table + 4;
711  BigReal *vdwb_i = vdwb_table + 4;
712  BigReal *r2_i = r2_table; *(r2_i++) = r2_delta;
713  BigReal r2_limit = simParams->limitDist * simParams->limitDist;
714  if ( r2_limit < r2_delta ) r2_limit = r2_delta;
715  int r2_delta_i = 0; // entry for r2 == r2_delta
716 
717 #ifdef NAMD_AVXTILES
718  {
719  avxTilesMode = 1;
720  if (!simParams->useAVXTiles)
721  avxTilesMode = 0;
722  if (avxTilesMode) {
723  if (simParams->vdwGeometricSigma) avxTilesMode = 2;
724  if ( simParams->fullDirectOn || simParams->FMAOn || PMEOn || MSMOn ||
725  simParams->FMMOn ) {
726  if ( simParams->longSplitting != C1)
727  avxTilesMode = 3;
728  } else
729  avxTilesMode = 3;
730  if (avxTilesMode == 1) {
731  const int table_dim = ljTable->get_table_dim();
732  Real A, B, A14, B14;
733  for (int i = 0; i < table_dim; i++)
734  for (int j = i+1; j < table_dim; j++)
735  if (params->get_vdw_pair_params(i, j, &A, &B, &A14, &B14))
736  avxTilesMode = 2;
737  }
738  if (avxTilesMode > 1)
739  iout << iINFO << "AVX-512 TILES WILL USE SHORT-RANGE INTERPOLATION ("
740  << avxTilesMode << ")\n";
741  else {
742  Parameters *params = Node::Object()->parameters;
743  const int num_params = params->get_num_vdw_params();
744  if ( avx_tiles_eps4_sigma ) delete [] avx_tiles_eps4_sigma;
745  if ( avx_tiles_eps4_sigma_14 ) delete [] avx_tiles_eps4_sigma_14;
746  avx_tiles_eps4_sigma = new float[num_params*2];
747  avx_tiles_eps4_sigma_14 = new float[num_params*2];
748  for (int i = 0; i < num_params; i++) {
749  Real sigma, sigma_14, epsilon, epsilon_14;
750  params->get_vdw_params(&sigma, &epsilon, &sigma_14,
751  &epsilon_14,i);
752  // Set the epsilon and epsilon_14 to zero if we do LJ-PME
753 //if (simParams->LJPMESerialOn) {
754  if (simParams->LJPMEOn) {
755  epsilon = epsilon_14 = 0.0;
756  }
757 //}
758  avx_tiles_eps4_sigma[i*2] = 4.0 * scaling * epsilon;
759  avx_tiles_eps4_sigma[i*2 + 1] = sigma;
760  avx_tiles_eps4_sigma_14[i*2] = 4.0 * scaling * epsilon_14;
761  avx_tiles_eps4_sigma_14[i*2 + 1] = sigma_14;
762  }
763  }
764  }
765  }
766 #endif
767 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
768  if ( knl_table_alloc ) delete [] knl_table_alloc;
769  if ( KNL_TABLE_MAX_R_1 < 1.f || KNL_TABLE_FACTOR < 1 ||
770  KNL_TABLE_FACTOR !=
771  static_cast<int>(1.0 / KNL_TABLE_MAX_R_1 * KNL_TABLE_SIZE))
772  NAMD_bug("Inconsistent KNL preprocessor settings.");
773 #ifdef NAMD_KNL
774  knl_table_alloc = new float[10*KNL_TABLE_SIZE];
775 #else
776  knl_table_alloc = new float[8*KNL_TABLE_SIZE];
777 #endif
778  knl_fast_ener_table = knl_table_alloc;
779  knl_fast_grad_table = knl_table_alloc + KNL_TABLE_SIZE;
780  knl_scor_ener_table = knl_table_alloc + 2*KNL_TABLE_SIZE;
781  knl_scor_grad_table = knl_table_alloc + 3*KNL_TABLE_SIZE;
782  knl_slow_ener_table = knl_table_alloc + 4*KNL_TABLE_SIZE;
783  knl_slow_grad_table = knl_table_alloc + 5*KNL_TABLE_SIZE;
784  knl_excl_ener_table = knl_table_alloc + 6*KNL_TABLE_SIZE;
785  knl_excl_grad_table = knl_table_alloc + 7*KNL_TABLE_SIZE;
786  knl_fast_ener_table[0] = 0.;
787  knl_fast_grad_table[0] = 0.;
788  knl_scor_ener_table[0] = 0.;
789  knl_scor_grad_table[0] = 0.;
790  knl_slow_ener_table[0] = 0.;
791  knl_slow_grad_table[0] = 0.;
792  knl_excl_ener_table[0] = 0.;
793  knl_excl_grad_table[0] = 0.;
794 #ifdef NAMD_KNL
795  knl_corr_ener_table = knl_table_alloc + 8*KNL_TABLE_SIZE;
796  knl_corr_grad_table = knl_table_alloc + 9*KNL_TABLE_SIZE;
797  knl_corr_ener_table[0] = 0.;
798  knl_corr_grad_table[0] = 0.;
799 #endif
800  for ( int knl_table = 0; knl_table < 2; ++knl_table ) {
801  int nn = n;
802  if ( knl_table ) {
803  nn = KNL_TABLE_SIZE-1;
804  }
805  for ( i=1; i<nn; ++i ) {
806 #else
807  // fill in the table, fix up i==0 (r2==0) below
808  for ( i=1; i<n; ++i ) {
809 #endif
810 
811  const BigReal r2_base = r2_delta * ( 1 << (i/64) );
812  const BigReal r2_del = r2_base / 64.0;
813  BigReal r2 = r2_base - r2_delta + r2_del * (i%64);
814 
815  BigReal r = sqrt(r2);
816 
817 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
818  if ( knl_table ) {
819  r = (double)(KNL_TABLE_FACTOR-2)/(double)(i);
820  r2 = r*r;
821  } else
822 #endif
823  if ( r2 <= r2_limit ) r2_delta_i = i;
824 
825  const BigReal r_1 = 1.0/r;
826  const BigReal r_2 = 1.0/r2;
827 
828  // fast_ is defined as (full_ - slow_)
829  // corr_ and fast_ are both zero at the cutoff, full_ is not
830  // all three are approx 1/r at short distances
831 
832  // for actual interpolation, we use fast_ for fast forces and
833  // scor_ = slow_ + corr_ - full_ and slow_ for slow forces
834  // since these last two are of small magnitude
835 
836  BigReal fast_energy, fast_gradient;
837  BigReal scor_energy, scor_gradient;
838  BigReal slow_energy, slow_gradient;
839 
840  // corr_ is PME direct sum, or similar correction term
841  // corr_energy is multiplied by r until later
842  // corr_gradient is multiplied by -r^2 until later
843  BigReal corr_energy, corr_gradient;
844 
845 
846  if ( PMEOn ) {
847  BigReal tmp_a = r * ewaldcof;
848  BigReal tmp_b = erfc(tmp_a);
849  corr_energy = tmp_b;
850  corr_gradient = pi_ewaldcof*exp(-(tmp_a*tmp_a))*r + tmp_b;
851  } else if ( MSMOn ) {
852  BigReal a_1 = 1.0/cutoff;
853  BigReal r_a = r * a_1;
854  BigReal g, dg;
855  SPOLY(&g, &dg, r_a, MSMSplit);
856  corr_energy = 1 - r_a * g;
857  corr_gradient = 1 + r_a*r_a * dg;
858  } else {
859  corr_energy = corr_gradient = 0;
860  }
861 
862  switch(splitType) {
863  case SPLIT_NONE:
864  fast_energy = 1.0/r;
865  fast_gradient = -1.0/r2;
866  scor_energy = scor_gradient = 0;
867  slow_energy = slow_gradient = 0;
868  break;
869  case SPLIT_SHIFT: {
870  BigReal shiftVal = r2/cutoff2 - 1.0;
871  shiftVal *= shiftVal;
872  BigReal dShiftVal = 2.0 * (r2/cutoff2 - 1.0) * 2.0*r/cutoff2;
873  fast_energy = shiftVal/r;
874  fast_gradient = dShiftVal/r - shiftVal/r2;
875  scor_energy = scor_gradient = 0;
876  slow_energy = slow_gradient = 0;
877  }
878  break;
879  case SPLIT_MARTINI: {
880  // in Martini, the Coulomb switching distance is zero
881  const BigReal COUL_SWITCH = 0.;
882  // Gromacs shifting function
883  const BigReal p1 = 1.;
884  BigReal A1 = p1 * ((p1+1)*COUL_SWITCH-(p1+4)*cutoff)/(pow(cutoff,p1+2)*pow(cutoff-COUL_SWITCH,2));
885  BigReal B1 = -p1 * ((p1+1)*COUL_SWITCH-(p1+3)*cutoff)/(pow(cutoff,p1+2)*pow(cutoff-COUL_SWITCH,3));
886  BigReal X1 = 1.0/pow(cutoff,p1)-A1/3.0*pow(cutoff-COUL_SWITCH,3)-B1/4.0*pow(cutoff-COUL_SWITCH,4);
887  BigReal r12 = (r-COUL_SWITCH)*(r-COUL_SWITCH);
888  BigReal r13 = (r-COUL_SWITCH)*(r-COUL_SWITCH)*(r-COUL_SWITCH);
889  BigReal shiftVal = -(A1/3.0)*r13 - (B1/4.0)*r12*r12 - X1;
890  BigReal dShiftVal = -A1*r12 - B1*r13;
891  fast_energy = (1/r) + shiftVal;
892  fast_gradient = -1/(r2) + dShiftVal;
893  scor_energy = scor_gradient = 0;
894  slow_energy = slow_gradient = 0;
895  }
896  break;
897  case SPLIT_C1:
898  // calculate actual energy and gradient
899  slow_energy = 0.5/cutoff * (3.0 - (r2/cutoff2));
900  slow_gradient = -1.0/cutoff2 * (r/cutoff);
901  // calculate scor from slow and corr
902  scor_energy = slow_energy + (corr_energy - 1.0)/r;
903  scor_gradient = slow_gradient - (corr_gradient - 1.0)/r2;
904  // calculate fast from slow
905  fast_energy = 1.0/r - slow_energy;
906  fast_gradient = -1.0/r2 - slow_gradient;
907  break;
908  case SPLIT_C2:
909  //
910  // Quintic splitting function contributed by
911  // Bruce Berne, Ruhong Zhou, and Joe Morrone
912  //
913  // calculate actual energy and gradient
914  slow_energy = r2/(cutoff*cutoff2) * (6.0 * (r2/cutoff2)
915  - 15.0*(r/cutoff) + 10.0);
916  slow_gradient = r/(cutoff*cutoff2) * (24.0 * (r2/cutoff2)
917  - 45.0 *(r/cutoff) + 20.0);
918  // calculate scor from slow and corr
919  scor_energy = slow_energy + (corr_energy - 1.0)/r;
920  scor_gradient = slow_gradient - (corr_gradient - 1.0)/r2;
921  // calculate fast from slow
922  fast_energy = 1.0/r - slow_energy;
923  fast_gradient = -1.0/r2 - slow_gradient;
924  break;
925  }
926 
927  // foo_gradient is calculated as ( d foo_energy / d r )
928  // and now divided by 2r to get ( d foo_energy / d r2 )
929 
930  fast_gradient *= 0.5 * r_1;
931  scor_gradient *= 0.5 * r_1;
932  slow_gradient *= 0.5 * r_1;
933 
934  // let modf be 1 if excluded, 1-scale14 if modified, 0 otherwise,
935  // add scor_ - modf * slow_ to slow terms and
936  // add fast_ - modf * fast_ to fast terms.
937 
938  BigReal vdwa_energy, vdwa_gradient;
939  BigReal vdwb_energy, vdwb_gradient;
940 
941  const BigReal r_6 = r_2*r_2*r_2;
942  const BigReal r_12 = r_6*r_6;
943 
944  // Lennard-Jones switching function
945  if ( simParams->vdwForceSwitching ) { // switch force
947 
948  // from Steinbach & Brooks, JCC 15, pgs 667-683, 1994, eqns 10-13
949  if ( r2 > switchOn2 ) {
950  BigReal tmpa = r_6 - cutoff_6;
951  vdwa_energy = k_vdwa * tmpa * tmpa;
952  BigReal tmpb = r_1 * r_2 - cutoff_3;
953  vdwb_energy = k_vdwb * tmpb * tmpb;
954  vdwa_gradient = -6.0 * k_vdwa * tmpa * r_2 * r_6;
955  vdwb_gradient = -3.0 * k_vdwb * tmpb * r_2 * r_2 * r_1;
956  } else {
957  vdwa_energy = r_12 + v_vdwa;
958  vdwb_energy = r_6 + v_vdwb;
959  vdwa_gradient = -6.0 * r_2 * r_12;
960  vdwb_gradient = -3.0 * r_2 * r_6;
961  }
962  } else if ( simParams->martiniSwitching ) { // switching fxn for Martini RBCG
964 
965  BigReal r12 = (r-switchOn)*(r-switchOn); BigReal r13 = (r-switchOn)*(r-switchOn)*(r-switchOn);
966 
967  BigReal p6 = 6;
968  BigReal A6 = p6 * ((p6+1)*switchOn-(p6+4)*cutoff)/(pow(cutoff,p6+2)*pow(cutoff-switchOn,2));
969  BigReal B6 = -p6 * ((p6+1)*switchOn-(p6+3)*cutoff)/(pow(cutoff,p6+2)*pow(cutoff-switchOn,3));
970  BigReal C6 = 1.0/pow(cutoff,p6)-A6/3.0*pow(cutoff-switchOn,3)-B6/4.0*pow(cutoff-switchOn,4);
971 
972  BigReal p12 = 12;
973  BigReal A12 = p12 * ((p12+1)*switchOn-(p12+4)*cutoff)/(pow(cutoff,p12+2)*pow(cutoff-switchOn,2));
974  BigReal B12 = -p12 * ((p12+1)*switchOn-(p12+3)*cutoff)/(pow(cutoff,p12+2)*pow(cutoff-switchOn,3));
975  BigReal C12 = 1.0/pow(cutoff,p12)-A12/3.0*pow(cutoff-switchOn,3)-B12/4.0*pow(cutoff-switchOn,4);
976 
977  BigReal LJshifttempA = -(A12/3)*r13 - (B12/4)*r12*r12 - C12;
978  BigReal LJshifttempB = -(A6/3)*r13 - (B6/4)*r12*r12 - C6;
979  const BigReal shiftValA = // used for Lennard-Jones
980  ( r2 > switchOn2 ? LJshifttempA : -C12);
981  const BigReal shiftValB = // used for Lennard-Jones
982  ( r2 > switchOn2 ? LJshifttempB : -C6);
983 
984  BigReal LJdshifttempA = -A12*r12 - B12*r13;
985  BigReal LJdshifttempB = -A6*r12 - B6*r13;
986  const BigReal dshiftValA = // used for Lennard-Jones
987  ( r2 > switchOn2 ? LJdshifttempA*0.5*r_1 : 0 );
988  const BigReal dshiftValB = // used for Lennard-Jones
989  ( r2 > switchOn2 ? LJdshifttempB*0.5*r_1 : 0 );
990 
991 
992 
993 
994  //have not addressed r > cutoff
995 
996  // dshiftValA*= 0.5*r_1;
997  // dshiftValB*= 0.5*r_1;
998 
999  vdwa_energy = r_12 + shiftValA;
1000  vdwb_energy = r_6 + shiftValB;
1001 
1002  vdwa_gradient = -6/pow(r,14) + dshiftValA ;
1003  vdwb_gradient = -3/pow(r,8) + dshiftValB;
1004 
1005  } else { // switch energy
1007 
1008  const BigReal c2 = cutoff2-r2;
1009  const BigReal c4 = c2*(c3-2.0*c2);
1010  const BigReal switchVal = // used for Lennard-Jones
1011  ( r2 > switchOn2 ? c2*c4*c1 : 1.0 );
1012  const BigReal dSwitchVal = // d switchVal / d r2
1013  ( r2 > switchOn2 ? 2*c1*(c2*c2-c4) : 0.0 );
1014 
1015  vdwa_energy = switchVal * r_12;
1016  vdwb_energy = switchVal * r_6;
1017 
1018  vdwa_gradient = ( dSwitchVal - 6.0 * switchVal * r_2 ) * r_12;
1019  vdwb_gradient = ( dSwitchVal - 3.0 * switchVal * r_2 ) * r_6;
1020  }
1021 
1022 
1023 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
1024  if ( knl_table ) {
1025  knl_fast_ener_table[i] = -1.*fast_energy;
1026  knl_fast_grad_table[i] = -2.*fast_gradient;
1027  knl_scor_ener_table[i] = -1.*scor_energy;
1028  knl_scor_grad_table[i] = -2.*scor_gradient;
1029  knl_slow_ener_table[i] = (-1.*scor_energy - (scale14-1)*slow_energy) /
1030  scale14;
1031  knl_slow_grad_table[i] = (-2.*scor_gradient -
1032  (scale14-1)*2.*slow_gradient) / scale14;
1033  knl_excl_ener_table[i] = slow_energy - scor_energy;
1034  knl_excl_grad_table[i] = 2.*(slow_gradient - scor_gradient);
1035 #ifdef NAMD_KNL
1036  knl_corr_ener_table[i] = -1.*(fast_energy + scor_energy);
1037  knl_corr_grad_table[i] = -2.*(fast_gradient + scor_gradient);
1038 #endif
1039  if ( i == nn-1 ) {
1040  knl_fast_ener_table[nn] = knl_fast_ener_table[i];
1041  knl_fast_grad_table[nn] = knl_fast_grad_table[i];
1042  knl_scor_ener_table[nn] = knl_scor_ener_table[i];
1043  knl_scor_grad_table[nn] = knl_scor_grad_table[i];
1044  knl_slow_ener_table[nn] = knl_slow_ener_table[i];
1045  knl_slow_grad_table[nn] = knl_slow_grad_table[i];
1046  knl_excl_ener_table[nn] = knl_excl_ener_table[i];
1047  knl_excl_grad_table[nn] = knl_excl_grad_table[i];
1048 #ifdef NAMD_KNL
1049  knl_corr_ener_table[nn] = knl_corr_ener_table[i];
1050  knl_corr_grad_table[nn] = knl_corr_grad_table[i];
1051 #endif
1052  }
1053  } else {
1054 #endif
1055  *(fast_i++) = fast_energy;
1056  *(fast_i++) = fast_gradient;
1057  *(fast_i++) = 0;
1058  *(fast_i++) = 0;
1059  *(scor_i++) = scor_energy;
1060  *(scor_i++) = scor_gradient;
1061  *(scor_i++) = 0;
1062  *(scor_i++) = 0;
1063  *(slow_i++) = slow_energy;
1064  *(slow_i++) = slow_gradient;
1065  *(slow_i++) = 0;
1066  *(slow_i++) = 0;
1067  *(vdwa_i++) = vdwa_energy;
1068  *(vdwa_i++) = vdwa_gradient;
1069  *(vdwa_i++) = 0;
1070  *(vdwa_i++) = 0;
1071  *(vdwb_i++) = vdwb_energy;
1072  *(vdwb_i++) = vdwb_gradient;
1073  *(vdwb_i++) = 0;
1074  *(vdwb_i++) = 0;
1075  *(r2_i++) = r2 + r2_delta;
1076 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
1077  }
1078 #endif
1079 
1080  }
1081 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
1082  } // knl_table loop
1083 #endif
1084 
1085  if ( ! r2_delta_i ) {
1086  NAMD_bug("Failed to find table entry for r2 == r2_limit\n");
1087  }
1088  if ( r2_table[r2_delta_i] > r2_limit + r2_delta ) {
1089  NAMD_bug("Found bad table entry for r2 == r2_limit\n");
1090  }
1091 
1092  int j;
1093  const char *table_name = "XXXX";
1094  int smooth_short = 0;
1095  for ( j=0; j<5; ++j ) {
1096  BigReal *t0 = 0;
1097  switch (j) {
1098  case 0:
1099  t0 = fast_table;
1100  table_name = "FAST";
1101  smooth_short = 1;
1102  break;
1103  case 1:
1104  t0 = scor_table;
1105  table_name = "SCOR";
1106  smooth_short = 0;
1107  break;
1108  case 2:
1109  t0 = slow_table;
1110  table_name = "SLOW";
1111  smooth_short = 0;
1112  break;
1113  case 3:
1114  t0 = vdwa_table;
1115  table_name = "VDWA";
1116  smooth_short = 1;
1117  break;
1118  case 4:
1119  t0 = vdwb_table;
1120  table_name = "VDWB";
1121  smooth_short = 1;
1122  break;
1123  }
1124  // patch up data for i=0
1125  t0[0] = t0[4] - t0[5] * ( r2_delta / 64.0 ); // energy
1126  t0[1] = t0[5]; // gradient
1127  t0[2] = 0;
1128  t0[3] = 0;
1129  if ( smooth_short ) {
1130  BigReal energy0 = t0[4*r2_delta_i];
1131  BigReal gradient0 = t0[4*r2_delta_i+1];
1132  BigReal r20 = r2_table[r2_delta_i];
1133  t0[0] = energy0 - gradient0 * (r20 - r2_table[0]); // energy
1134  t0[1] = gradient0; // gradient
1135  }
1136  BigReal *t;
1137  for ( i=0,t=t0; i<(n-1); ++i,t+=4 ) {
1138  BigReal x = ( r2_delta * ( 1 << (i/64) ) ) / 64.0;
1139  if ( r2_table[i+1] != r2_table[i] + x ) {
1140  NAMD_bug("Bad table delta calculation.\n");
1141  }
1142  if ( smooth_short && i+1 < r2_delta_i ) {
1143  BigReal energy0 = t0[4*r2_delta_i];
1144  BigReal gradient0 = t0[4*r2_delta_i+1];
1145  BigReal r20 = r2_table[r2_delta_i];
1146  t[4] = energy0 - gradient0 * (r20 - r2_table[i+1]); // energy
1147  t[5] = gradient0; // gradient
1148  }
1149  BigReal v1 = t[0];
1150  BigReal g1 = t[1];
1151  BigReal v2 = t[4];
1152  BigReal g2 = t[5];
1153  // explicit formulas for v1 + g1 x + c x^2 + d x^3
1154  BigReal c = ( 3.0 * (v2 - v1) - x * (2.0 * g1 + g2) ) / ( x * x );
1155  BigReal d = ( -2.0 * (v2 - v1) + x * (g1 + g2) ) / ( x * x * x );
1156  // since v2 - v1 is imprecise, we refine c and d numerically
1157  // important because we need accurate forces (more than energies!)
1158  for ( int k=0; k < 2; ++k ) {
1159  BigReal dv = (v1 - v2) + ( ( d * x + c ) * x + g1 ) * x;
1160  BigReal dg = (g1 - g2) + ( 3.0 * d * x + 2.0 * c ) * x;
1161  c -= ( 3.0 * dv - x * dg ) / ( x * x );
1162  d -= ( -2.0 * dv + x * dg ) / ( x * x * x );
1163  }
1164  // store in the array;
1165  t[2] = c; t[3] = d;
1166  }
1167 
1168  if ( ! CkMyPe() ) {
1169  BigReal dvmax = 0;
1170  BigReal dgmax = 0;
1171  BigReal dvmax_r = 0;
1172  BigReal dgmax_r = 0;
1173  BigReal fdvmax = 0;
1174  BigReal fdgmax = 0;
1175  BigReal fdvmax_r = 0;
1176  BigReal fdgmax_r = 0;
1177  BigReal dgcdamax = 0;
1178  BigReal dgcdimax = 0;
1179  BigReal dgcaimax = 0;
1180  BigReal dgcdamax_r = 0;
1181  BigReal dgcdimax_r = 0;
1182  BigReal dgcaimax_r = 0;
1183  BigReal fdgcdamax = 0;
1184  BigReal fdgcdimax = 0;
1185  BigReal fdgcaimax = 0;
1186  BigReal fdgcdamax_r = 0;
1187  BigReal fdgcdimax_r = 0;
1188  BigReal fdgcaimax_r = 0;
1189  BigReal gcm = fabs(t0[1]); // gradient magnitude running average
1190  for ( i=0,t=t0; i<(n-1); ++i,t+=4 ) {
1191  const BigReal r2_base = r2_delta * ( 1 << (i/64) );
1192  const BigReal r2_del = r2_base / 64.0;
1193  const BigReal r2 = r2_base - r2_delta + r2_del * (i%64);
1194  const BigReal r = sqrt(r2);
1195  if ( r > cutoff ) break;
1196  BigReal x = r2_del;
1197  BigReal dv = ( ( t[3] * x + t[2] ) * x + t[1] ) * x + t[0] - t[4];
1198  BigReal dg = ( 3.0 * t[3] * x + 2.0 * t[2] ) * x + t[1] - t[5];
1199  if ( t[4] != 0. && fabs(dv/t[4]) > fdvmax ) {
1200  fdvmax = fabs(dv/t[4]); fdvmax_r = r;
1201  }
1202  if ( fabs(dv) > dvmax ) {
1203  dvmax = fabs(dv); dvmax_r = r;
1204  }
1205  if ( t[5] != 0. && fabs(dg/t[5]) > fdgmax ) {
1206  fdgmax = fabs(dg/t[5]); fdgmax_r = r;
1207  }
1208  if ( fabs(dg) > dgmax ) {
1209  dgmax = fabs(dg); dgmax_r = r;
1210  }
1211  BigReal gcd = (t[4] - t[0]) / x; // centered difference gradient
1212  BigReal gcd_prec = (fabs(t[0]) + fabs(t[4])) * 1.e-15 / x; // roundoff
1213  gcm = 0.9 * gcm + 0.1 * fabs(t[5]); // magnitude running average
1214  BigReal gca = 0.5 * (t[1] + t[5]); // centered average gradient
1215  BigReal gci = ( 0.75 * t[3] * x + t[2] ) * x + t[1]; // interpolated
1216  BigReal rc = sqrt(r2 + 0.5 * x);
1217  BigReal dgcda = gcd - gca;
1218  if ( dgcda != 0. && fabs(dgcda) < gcd_prec ) {
1219  // CkPrintf("ERROR %g < PREC %g AT %g AVG VAL %g\n", dgcda, gcd_prec, rc, gca);
1220  dgcda = 0.;
1221  }
1222  BigReal dgcdi = gcd - gci;
1223  if ( dgcdi != 0. && fabs(dgcdi) < gcd_prec ) {
1224  // CkPrintf("ERROR %g < PREC %g AT %g INT VAL %g\n", dgcdi, gcd_prec, rc, gci);
1225  dgcdi = 0.;
1226  }
1227  BigReal dgcai = gca - gci;
1228  if ( t[1]*t[5] > 0. && gcm != 0. && fabs(dgcda/gcm) > fdgcdamax ) {
1229  fdgcdamax = fabs(dgcda/gcm); fdgcdamax_r = rc;
1230  }
1231  if ( fabs(dgcda) > fdgcdamax ) {
1232  dgcdamax = fabs(dgcda); dgcdamax_r = rc;
1233  }
1234  if ( t[1]*t[5] > 0. && gcm != 0. && fabs(dgcdi/gcm) > fdgcdimax ) {
1235  fdgcdimax = fabs(dgcdi/gcm); fdgcdimax_r = rc;
1236  }
1237  if ( fabs(dgcdi) > fdgcdimax ) {
1238  dgcdimax = fabs(dgcdi); dgcdimax_r = rc;
1239  }
1240  if ( t[1]*t[5] > 0. && gcm != 0. && fabs(dgcai/gcm) > fdgcaimax ) {
1241  fdgcaimax = fabs(dgcai/gcm); fdgcaimax_r = rc;
1242  }
1243  if ( fabs(dgcai) > fdgcaimax ) {
1244  dgcaimax = fabs(dgcai); dgcaimax_r = rc;
1245  }
1246 #if 0
1247  CkPrintf("TABLE %s %g %g %g %g\n",table_name,rc,dgcda/gcm,dgcda,gci);
1248  if (dv != 0.) CkPrintf("TABLE %d ENERGY ERROR %g AT %g (%d)\n",j,dv,r,i);
1249  if (dg != 0.) CkPrintf("TABLE %d FORCE ERROR %g AT %g (%d)\n",j,dg,r,i);
1250 #endif
1251  }
1252  if ( dvmax != 0.0 ) {
1253  iout << iINFO << "ABSOLUTE IMPRECISION IN " << table_name <<
1254  " TABLE ENERGY: " << dvmax << " AT " << dvmax_r << "\n" << endi;
1255  }
1256  if ( fdvmax != 0.0 ) {
1257  iout << iINFO << "RELATIVE IMPRECISION IN " << table_name <<
1258  " TABLE ENERGY: " << fdvmax << " AT " << fdvmax_r << "\n" << endi;
1259  }
1260  if ( dgmax != 0.0 ) {
1261  iout << iINFO << "ABSOLUTE IMPRECISION IN " << table_name <<
1262  " TABLE FORCE: " << dgmax << " AT " << dgmax_r << "\n" << endi;
1263  }
1264  if ( fdgmax != 0.0 ) {
1265  iout << iINFO << "RELATIVE IMPRECISION IN " << table_name <<
1266  " TABLE FORCE: " << fdgmax << " AT " << fdgmax_r << "\n" << endi;
1267  }
1268  if (fdgcdamax != 0.0 ) {
1269  iout << iINFO << "INCONSISTENCY IN " << table_name <<
1270  " TABLE ENERGY VS FORCE: " << fdgcdamax << " AT " << fdgcdamax_r << "\n" << endi;
1271  if ( fdgcdamax > 0.1 ) {
1272  iout << iERROR << "\n";
1273  iout << iERROR << "CALCULATED " << table_name <<
1274  " FORCE MAY NOT MATCH ENERGY! POSSIBLE BUG!\n";
1275  iout << iERROR << "\n";
1276  }
1277  }
1278  if (0 && fdgcdimax != 0.0 ) {
1279  iout << iINFO << "INCONSISTENCY IN " << table_name <<
1280  " TABLE ENERGY VS FORCE: " << fdgcdimax << " AT " << fdgcdimax_r << "\n" << endi;
1281  }
1282  if ( 0 && fdgcaimax != 0.0 ) {
1283  iout << iINFO << "INCONSISTENCY IN " << table_name <<
1284  " TABLE AVG VS INT FORCE: " << fdgcaimax << " AT " << fdgcaimax_r << "\n" << endi;
1285  }
1286  }
1287 
1288  }
1289 
1290  for ( i=0; i<4*n; ++i ) {
1291  corr_table[i] = fast_table[i] + scor_table[i];
1292  full_table[i] = fast_table[i] + slow_table[i];
1293  }
1294 
1295 #if 0
1296  for ( i=0; i<n; ++i ) {
1297  for ( int j=0; j<4; ++j ) {
1298  table_short[16*i+6-2*j] = table_noshort[16*i+6-2*j] = vdwa_table[4*i+j];
1299  table_short[16*i+7-2*j] = table_noshort[16*i+7-2*j] = vdwb_table[4*i+j];
1300  table_short[16*i+8+3-j] = fast_table[4*i+j];
1301  table_short[16*i+12+3-j] = scor_table[4*i+j];
1302  table_noshort[16*i+8+3-j] = corr_table[4*i+j];
1303  table_noshort[16*i+12+3-j] = full_table[4*i+j];
1304  }
1305  }
1306 #endif
1307 
1308  for ( i=0; i<n; ++i ) {
1309  table_short[16*i+0] = table_noshort[16*i+0] = -6.*vdwa_table[4*i+3];
1310  table_short[16*i+1] = table_noshort[16*i+1] = -4.*vdwa_table[4*i+2];
1311  table_short[16*i+2] = table_noshort[16*i+2] = -2.*vdwa_table[4*i+1];
1312  table_short[16*i+3] = table_noshort[16*i+3] = -1.*vdwa_table[4*i+0];
1313 
1314  table_short[16*i+4] = table_noshort[16*i+4] = -6.*vdwb_table[4*i+3];
1315  table_short[16*i+5] = table_noshort[16*i+5] = -4.*vdwb_table[4*i+2];
1316  table_short[16*i+6] = table_noshort[16*i+6] = -2.*vdwb_table[4*i+1];
1317  table_short[16*i+7] = table_noshort[16*i+7] = -1.*vdwb_table[4*i+0];
1318 
1319  table_short[16*i+8] = -6.*fast_table[4*i+3];
1320  table_short[16*i+9] = -4.*fast_table[4*i+2];
1321  table_short[16*i+10] = -2.*fast_table[4*i+1];
1322  table_short[16*i+11] = -1.*fast_table[4*i+0];
1323 
1324  table_noshort[16*i+8] = -6.*corr_table[4*i+3];
1325  table_noshort[16*i+9] = -4.*corr_table[4*i+2];
1326  table_noshort[16*i+10] = -2.*corr_table[4*i+1];
1327  table_noshort[16*i+11] = -1.*corr_table[4*i+0];
1328 
1329  table_short[16*i+12] = -6.*scor_table[4*i+3];
1330  table_short[16*i+13] = -4.*scor_table[4*i+2];
1331  table_short[16*i+14] = -2.*scor_table[4*i+1];
1332  table_short[16*i+15] = -1.*scor_table[4*i+0];
1333 
1334  table_noshort[16*i+12] = -6.*full_table[4*i+3];
1335  table_noshort[16*i+13] = -4.*full_table[4*i+2];
1336  table_noshort[16*i+14] = -2.*full_table[4*i+1];
1337  table_noshort[16*i+15] = -1.*full_table[4*i+0];
1338  }
1339 
1340 #if 0
1341  char fname[100];
1342  sprintf(fname,"/tmp/namd.table.pe%d.dat",CkMyPe());
1343  FILE *f = fopen(fname,"w");
1344  for ( i=0; i<(n-1); ++i ) {
1345  const BigReal r2_base = r2_delta * ( 1 << (i/64) );
1346  const BigReal r2_del = r2_base / 64.0;
1347  const BigReal r2 = r2_base - r2_delta + r2_del * (i%64);
1348  BigReal *t;
1349  if ( r2 + r2_delta != r2_table[i] ) fprintf(f,"r2 error! ");
1350  fprintf(f,"%g",r2);
1351  t = fast_table + 4*i;
1352  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1353  t = scor_table + 4*i;
1354  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1355  t = slow_table + 4*i;
1356  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1357  t = corr_table + 4*i;
1358  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1359  t = full_table + 4*i;
1360  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1361  t = vdwa_table + 4*i;
1362  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1363  t = vdwb_table + 4*i;
1364  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1365  fprintf(f,"\n");
1366  }
1367  fclose(f);
1368 #endif
1369 
1370  //Flip slow table to match table_four_i
1371  for ( i=0; i<n; ++i ) {
1372  BigReal tmp0, tmp1, tmp2, tmp3;
1373  tmp0 = slow_table [i*4 + 0];
1374  tmp1 = slow_table [i*4 + 1];
1375  tmp2 = slow_table [i*4 + 2];
1376  tmp3 = slow_table [i*4 + 3];
1377 
1378  slow_table [i*4 + 0] = tmp3;
1379  slow_table [i*4 + 1] = tmp2;
1380  slow_table [i*4 + 2] = tmp1;
1381  slow_table [i*4 + 3] = tmp0;
1382  }
1383 
1384  #ifdef NAMD_MIC
1385  send_build_mic_force_table();
1386  #endif
1387 }
1388 
static Node * Object()
Definition: Node.h:86
static void calc_pair_fullelect_pprof(nonbonded *)
static BigReal * fast_table
#define SCALED14
Definition: SimParameters.h:46
static void calc_pair_energy_merge_fullelect_tabener(nonbonded *)
static void calc_self_energy_go(nonbonded *)
std::ostream & iINFO(std::ostream &s)
Definition: InfoStream.C:81
static void calc_self_energy_merge_fullelect_ti(nonbonded *)
static BigReal * scor_table
static void calc_self_energy_disp_fullelect(nonbonded *)
static void(* calcMergeDispSelfEnergy)(nonbonded *)
static void calc_pair_les(nonbonded *)
static void calc_self_energy_slow_fullelect_fep(nonbonded *)
static void calc_pair_merge_fullelect(nonbonded *)
int columnsize
Definition: Parameters.h:320
static void calc_self_energy_merge_fullelect_int(nonbonded *)
static void calc_self_energy_slow_fullelect(nonbonded *)
#define XPLOR
Definition: SimParameters.h:58
static void calc_self_energy_merge_fullelect_tabener(nonbonded *)
static void calc_self_energy_slow_fullelect_ti(nonbonded *)
static void calc_self_energy_fullelect_int(nonbonded *)
static void submitReductionData(BigReal *, SubmitReduction *)
static void(* calcDispPair)(nonbonded *)
static void calc_self_ti(nonbonded *)
static void calc_self_fullelect_pprof(nonbonded *)
static void calc_self_tabener(nonbonded *)
static void calc_self_energy_fullelect(nonbonded *)
static void calc_pair_slow_fullelect_ti(nonbonded *)
#define SHARP
Definition: SimParameters.h:57
static void(* calcSelf)(nonbonded *)
#define ADD_TENSOR(R, RL, D, DL)
Definition: ReductionMgr.h:33
static void calc_pair_merge_fullelect_tabener(nonbonded *)
static void calc_self_les(nonbonded *)
SimParameters * simParameters
Definition: Node.h:181
static void calc_pair_merge_fullelect_go(nonbonded *)
#define SPLIT_NONE
static void calc_pair_energy_merge_fullelect(nonbonded *)
static void calc_pair_slow_fullelect_pprof(nonbonded *)
static void calc_pair_energy_disp_merge_fullelect(nonbonded *)
static const Molecule * mol
static void calc_pair_energy_fullelect_fep(nonbonded *)
static void calc_self_energy_fullelect_pprof(nonbonded *)
float Real
Definition: common.h:118
BigReal & item(int i)
Definition: ReductionMgr.h:336
static void calc_self_energy_fullelect_les(nonbonded *)
static void calc_self_energy_fullelect_ti(nonbonded *)
std::ostream & endi(std::ostream &s)
Definition: InfoStream.C:54
static void calc_self_fullelect(nonbonded *)
#define VDW_SWITCH_MODE_MARTINI
static void calc_self_energy_ti(nonbonded *)
static BigReal * vdwa_table
static void calc_self_energy_int(nonbonded *)
static void submitPressureProfileData(BigReal *, SubmitReduction *)
static BigReal pressureProfileThickness
static void calc_pair_disp_fullelect(nonbonded *)
static void calc_pair_slow_fullelect(nonbonded *)
static void calc_pair(nonbonded *)
static void calc_self_go(nonbonded *)
#define iout
Definition: InfoStream.h:51
static void(* calcFullDispSelfEnergy)(nonbonded *)
static void(* calcMergePair)(nonbonded *)
static void calc_pair_energy_tabener(nonbonded *)
static void calc_self_slow_fullelect_pprof(nonbonded *)
static void calc_pair_energy_slow_fullelect_go(nonbonded *)
static void calc_self_energy_merge_fullelect_fep(nonbonded *)
static void(* calcMergePairEnergy)(nonbonded *)
static void calc_pair_energy_go(nonbonded *)
static void calc_pair_merge_fullelect_ti(nonbonded *)
#define C1
Definition: SimParameters.h:59
static void calc_self_disp_merge_fullelect(nonbonded *)
Molecule stores the structural information for the system.
Definition: Molecule.h:174
static BigReal * full_table
static void calc_pair_merge_fullelect_les(nonbonded *)
static void calc_pair_slow_fullelect_go(nonbonded *)
#define SPLIT_MARTINI
static void calc_pair_energy_merge_fullelect_fep(nonbonded *)
static void(* calcSlowPairEnergy)(nonbonded *)
static void(* calcPair)(nonbonded *)
static void(* calcMergeDispPairEnergy)(nonbonded *)
static void calc_self_energy_disp_merge_fullelect(nonbonded *)
void add(int nitems, const BigReal *arr)
Definition: ReductionMgr.h:361
static void(* calcSlowPair)(nonbonded *)
#define SPLIT_SHIFT
static void calc_pair_energy_fullelect_go(nonbonded *)
static void calc_pair_energy_slow_fullelect_tabener(nonbonded *)
static void calc_self_slow_fullelect(nonbonded *)
static void calc_self_energy_les(nonbonded *)
static void calc_pair_energy_fep(nonbonded *)
static void(* calcMergeSelfEnergy)(nonbonded *)
static void calc_pair_tabener(nonbonded *)
static void calc_pair_energy_pprof(nonbonded *)
static BigReal * table_noshort
static void calc_pair_energy_disp_fullelect(nonbonded *)
static void calc_self_energy_slow_fullelect_tabener(nonbonded *)
void NAMD_bug(const char *err_msg)
Definition: common.C:196
static void calc_self_energy_fullelect_tabener(nonbonded *)
static void calc_pair_energy_int(nonbonded *)
static BigReal pressureProfileMin
static void calc_self_slow_fullelect_tabener(nonbonded *)
static void calc_pair_energy_slow_fullelect_les(nonbonded *)
static void calc_pair_energy_ti(nonbonded *)
static void calc_pair_disp_merge_fullelect(nonbonded *)
static void calc_pair_energy_slow_fullelect_fep(nonbonded *)
static void calc_self_slow_fullelect_ti(nonbonded *)
static void calc_pair_slow_fullelect_les(nonbonded *)
static void calc_pair_fullelect_ti(nonbonded *)
static void calc_pair_energy(nonbonded *)
static BigReal * table_ener
#define C2
Definition: SimParameters.h:60
int Bool
Definition: common.h:142
static void calc_pair_pprof(nonbonded *)
#define ADD_VECTOR(R, RL, D, DL)
Definition: ReductionMgr.h:23
static void calc_pair_energy_fullelect_ti(nonbonded *)
int get_table_dim() const
Definition: LJTable.h:44
static void calc_self_energy_merge_fullelect_les(nonbonded *)
static void calc_self_slow_fullelect_go(nonbonded *)
static void calc_pair_energy_merge_fullelect_go(nonbonded *)
static void calc_error(nonbonded *)
static void calc_self_energy_fullelect_go(nonbonded *)
static void(* calcDispSelfEnergy)(nonbonded *)
int get_vdw_pair_params(Index ind1, Index ind2, Real *, Real *, Real *, Real *)
Definition: Parameters.C:4646
static void calc_self_fullelect_tabener(nonbonded *)
static void(* calcFullSelf)(nonbonded *)
void NAMD_die(const char *err_msg)
Definition: common.C:148
static void calc_self_merge_fullelect_ti(nonbonded *)
static void(* calcSlowSelf)(nonbonded *)
static void(* calcMergeDispSelf)(nonbonded *)
#define SPLIT_C1
static void calc_self_fullelect_les(nonbonded *)
static void calc_self_merge_fullelect_go(nonbonded *)
int get_num_vdw_params(void)
Definition: Parameters.h:602
static void(* calcDispSelf)(nonbonded *)
static void(* calcDispPairEnergy)(nonbonded *)
static void calc_self_energy_merge_fullelect_go(nonbonded *)
static void calc_self_energy_merge_fullelect(nonbonded *)
static void select(void)
static void calc_pair_energy_fullelect_int(nonbonded *)
static void calc_pair_energy_merge_fullelect_pprof(nonbonded *)
static BigReal * lambda_table
static void calc_self_energy_fep(nonbonded *)
static void(* calcSlowSelfEnergy)(nonbonded *)
static void calc_pair_energy_slow_fullelect_pprof(nonbonded *)
Parameters * parameters
Definition: Node.h:180
static BigReal * slow_table
static void(* calcSelfEnergy)(nonbonded *)
static void(* calcPairEnergy)(nonbonded *)
static void calc_pair_fullelect_les(nonbonded *)
static void calc_pair_energy_les(nonbonded *)
#define simParams
Definition: Output.C:131
static void calc_self_merge_fullelect(nonbonded *)
static void(* calcFullDispPair)(nonbonded *)
static void calc_self_energy_tabener(nonbonded *)
static void calc_pair_energy_merge_fullelect_int(nonbonded *)
static void calc_self_energy_slow_fullelect_pprof(nonbonded *)
static void calc_self_energy_pprof(nonbonded *)
static void calc_pair_energy_fullelect_pprof(nonbonded *)
static void calc_pair_energy_disp(nonbonded *)
static void calc_pair_fullelect_go(nonbonded *)
static void calc_pair_energy_slow_fullelect(nonbonded *)
static void calc_pair_energy_fullelect_les(nonbonded *)
static BigReal * vdwb_table
static void calc_pair_energy_fullelect_tabener(nonbonded *)
#define SPLIT_C2
BigReal * table_ener
Definition: Parameters.h:321
static void(* calcFullPair)(nonbonded *)
#define VDW_SWITCH_MODE_FORCE
static void calc_pair_merge_fullelect_pprof(nonbonded *)
static const LJTable * ljTable
static void calc_self_energy_merge_fullelect_pprof(nonbonded *)
#define VDW_SWITCH_MODE_ENERGY
static void calc_self_disp_fullelect(nonbonded *)
static void(* calcFullPairEnergy)(nonbonded *)
static BigReal * corr_table
static void calc_self_energy_disp(nonbonded *)
static BigReal * table_short
static void calc_self(nonbonded *)
#define SPOLY(pg, pdg, ra, split)
Definition: msm_defn.h:140
static void calc_self_fullelect_ti(nonbonded *)
static void calc_self_disp(nonbonded *)
static void calc_pair_fullelect_tabener(nonbonded *)
static void calc_pair_energy_merge_fullelect_ti(nonbonded *)
std::ostream & iERROR(std::ostream &s)
Definition: InfoStream.C:83
static void(* calcFullDispPairEnergy)(nonbonded *)
static BigReal * table_alloc
static void calc_self_energy_fullelect_fep(nonbonded *)
static void calc_self_merge_fullelect_tabener(nonbonded *)
static BigReal alchVdwShiftCoeff
static void calc_pair_go(nonbonded *)
static void calc_pair_ti(nonbonded *)
static void(* calcFullDispSelf)(nonbonded *)
static void calc_self_energy(nonbonded *)
void get_vdw_params(Real *sigma, Real *epsilon, Real *sigma14, Real *epsilon14, Index index)
Definition: Parameters.h:568
static void calc_self_fullelect_go(nonbonded *)
static void calc_pair_energy_merge_fullelect_les(nonbonded *)
static void calc_self_pprof(nonbonded *)
static void(* calcMergeDispPair)(nonbonded *)
static void calc_self_merge_fullelect_les(nonbonded *)
Molecule * molecule
Definition: Node.h:179
static void calc_pair_slow_fullelect_tabener(nonbonded *)
static void calc_pair_energy_fullelect(nonbonded *)
static void calc_self_merge_fullelect_pprof(nonbonded *)
static void calc_self_energy_slow_fullelect_go(nonbonded *)
static void calc_pair_disp(nonbonded *)
static void calc_pair_energy_slow_fullelect_ti(nonbonded *)
static void(* calcMergeSelf)(nonbonded *)
static void calc_self_energy_slow_fullelect_les(nonbonded *)
double BigReal
Definition: common.h:123
static void(* calcFullSelfEnergy)(nonbonded *)
static void calc_pair_fullelect(nonbonded *)
static void calc_self_slow_fullelect_les(nonbonded *)