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 
145 
147 
148 // Ported by JLai -- JE - Go
151 int ComputeNonbondedUtil::goMethod; //6.3.11
152 // End of port -- JLai
153 
158 
163 
168 
173 
178 
179 // define splitting function
180 #define SPLIT_NONE 1
181 #define SPLIT_SHIFT 2
182 #define SPLIT_C1 3
183 #define SPLIT_XPLOR 4
184 #define SPLIT_C2 5
185 #define SPLIT_MARTINI 6
186 
188 {
191  reduction->item(REDUCTION_ELECT_ENERGY) += data[electEnergyIndex];
193  reduction->item(REDUCTION_LJ_ENERGY) += data[vdwEnergyIndex];
194  reduction->item(REDUCTION_LJ_ENERGY_SLOW) += data[fullVdwEnergyIndex];
195  // Ported by JLai
196  reduction->item(REDUCTION_GRO_LJ_ENERGY) += data[groLJEnergyIndex];
200  // End of port -- JLai
201 //fepb
202  reduction->item(REDUCTION_ELECT_ENERGY_F) += data[electEnergyIndex_s];
204  reduction->item(REDUCTION_LJ_ENERGY_F) += data[vdwEnergyIndex_s];
205 
212 //fepe
213  ADD_TENSOR(reduction,REDUCTION_VIRIAL_NBOND,data,virialIndex);
214  ADD_TENSOR(reduction,REDUCTION_VIRIAL_SLOW,data,fullElectVirialIndex);
215  ADD_VECTOR(reduction,REDUCTION_PAIR_VDW_FORCE,data,pairVDWForceIndex);
216  ADD_VECTOR(reduction,REDUCTION_PAIR_ELECT_FORCE,data,pairElectForceIndex);
217  reduction->item(REDUCTION_COMPUTE_CHECKSUM) += 1.;
218 }
219 
221  SubmitReduction *reduction)
222 {
223  if (!reduction) return;
224  int numAtomTypes = pressureProfileAtomTypes;
225  // For ease of calculation we stored interactions between types
226  // i and j in (ni+j). For efficiency now we coalesce the
227  // cross interactions so that just i<=j are stored.
228  const int arraysize = 3*pressureProfileSlabs;
229  size_t nelems = arraysize*(numAtomTypes*(numAtomTypes+1))/2;
230  BigReal *arr = new BigReal[nelems];
231  memset(arr, 0, nelems*sizeof(BigReal));
232 
233  int i, j;
234  for (i=0; i<numAtomTypes; i++) {
235  for (j=0; j<numAtomTypes; j++) {
236  int ii=i;
237  int jj=j;
238  if (ii > jj) { int tmp=ii; ii=jj; jj=tmp; }
239  const int reductionOffset = (ii*numAtomTypes - (ii*(ii+1))/2 + jj)*arraysize;
240  for (int k=0; k<arraysize; k++) {
241  arr[reductionOffset+k] += data[k];
242  }
243  data += arraysize;
244  }
245  }
246  // copy into reduction
247  reduction->add(nelems, arr);
248  delete [] arr;
249 }
250 
252  NAMD_bug("Tried to call missing nonbonded compute routine.");
253 }
254 
256 {
257  if ( CkMyRank() ) return;
258 
259  // These defaults die cleanly if nothing appropriate is assigned.
276 
278  Parameters * params = Node::Object()->parameters;
279 
280  table_ener = params->table_ener;
281  rowsize = params->rowsize;
282  columnsize = params->columnsize;
283 
284  commOnly = simParams->commOnly;
285  fixedAtomsOn = ( simParams->fixedAtomsOn && ! simParams->fixedAtomsForces );
286 
287  qmForcesOn = simParams->qmForcesOn ;
288 
289  cutoff = simParams->cutoff;
291  cutoff2_f = cutoff2;
292 
293 //fepb
294  alchFepOn = simParams->alchFepOn;
295  alchThermIntOn = simParams->alchThermIntOn;
296  alchWCAOn = simParams->alchWCAOn;
297  alchDecouple = simParams->alchDecouple;
298 
299  lesOn = simParams->lesOn;
300  lesScaling = lesFactor = 0;
301 
302  Bool tabulatedEnergies = simParams->tabulatedEnergies;
303  alchVdwShiftCoeff = simParams->alchVdwShiftCoeff;
304  vdwForceSwitching = simParams->vdwForceSwitching;
305 
306  delete [] lambda_table;
307  lambda_table = 0;
308 
309  pairInteractionOn = simParams->pairInteractionOn;
310  pairInteractionSelf = simParams->pairInteractionSelf;
311  pressureProfileOn = simParams->pressureProfileOn;
312 
313  // Ported by JLai -- Original JE - Go
314  goGroPair = simParams->goGroPair;
315  goForcesOn = simParams->goForcesOn;
316  goMethod = simParams->goMethod;
317  // End of port
318 
319  accelMDOn = simParams->accelMDOn;
320 
321  drudeNbthole = simParams->drudeOn && (simParams->drudeNbtholeCut > 0.0);
322 
323  if ( drudeNbthole ) {
324 // #if defined(NAMD_CUDA) || defined(NAMD_HIP)
325 // NAMD_die("drudeNbthole is not supported in CUDA version");
326 // #endif
327  if ( lesOn )
328  NAMD_die("drudeNbthole is not supported with locally enhanced sampling");
329  if ( pairInteractionOn )
330  NAMD_die("drudeNbthole is not supported with pair interaction calculation");
331  if ( pressureProfileOn )
332  NAMD_die("drudeNbthole is not supported with pressure profile calculation");
333  }
334 
335  if ( alchFepOn ) {
352  } else if ( alchThermIntOn ) {
369  } else if ( lesOn ) {
370 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
371  NAMD_die("Locally enhanced sampling is not supported in CUDA version");
372 #endif
373  lesFactor = simParams->lesFactor;
374  lesScaling = 1.0 / (double)lesFactor;
375  lambda_table = new BigReal[(lesFactor+1)*(lesFactor+1)];
376  for ( int ip=0; ip<=lesFactor; ++ip ) {
377  for ( int jp=0; jp<=lesFactor; ++jp ) {
378  BigReal lambda_pair = 1.0;
379  if (ip || jp ) {
380  if (ip && jp && ip != jp) {
381  lambda_pair = 0.0;
382  } else {
383  lambda_pair = lesScaling;
384  }
385  }
386  lambda_table[(lesFactor+1)*ip+jp] = lambda_pair;
387  }
388  }
405  } else if ( pressureProfileOn) {
406 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
407  NAMD_die("Pressure profile calculation is not supported in CUDA version");
408 #endif
409  pressureProfileSlabs = simParams->pressureProfileSlabs;
410  pressureProfileAtomTypes = simParams->pressureProfileAtomTypes;
411 
428  } else if ( pairInteractionOn ) {
429 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
430  NAMD_die("Pair interaction calculation is not supported in CUDA version");
431 #endif
438  } else if ( tabulatedEnergies ) {
439 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
440  NAMD_die("Tabulated energies is not supported in CUDA version");
441 #endif
458  } else if ( goForcesOn ) {
459 #ifdef NAMD_CUDA
460  NAMD_die("Go forces is not supported in CUDA version");
461 #endif
478  } else {
499  }
500 
501 //fepe
502 
503  dielectric_1 = 1.0/simParams->dielectric;
504  if ( simParams->soluteScalingOn ) {
505  delete ljTable;
506  ljTable = 0;
507  }
508  if ( ! ljTable ) ljTable = new LJTable;
510  scaling = simParams->nonbondedScaling;
511  if ( simParams->exclude == SCALED14 )
512  {
513  scale14 = simParams->scale14;
514  }
515  else
516  {
517  scale14 = 1.;
518  }
519  if ( simParams->switchingActive )
520  {
521  switchOn = simParams->switchingDist;
522  switchOn_1 = 1.0/switchOn;
523  // d0 = 1.0/(cutoff-switchOn);
525  c0 = 1.0/(cutoff2-switchOn2);
526 
527  if ( simParams->vdwForceSwitching ) {
528  double switchOn3 = switchOn * switchOn2;
529  double cutoff3 = cutoff * cutoff2;
530  double switchOn6 = switchOn3 * switchOn3;
531  double cutoff6 = cutoff3 * cutoff3;
532  v_vdwa_f = v_vdwa = -1. / ( switchOn6 * cutoff6 );
533  v_vdwb_f = v_vdwb = -1. / ( switchOn3 * cutoff3 );
534  k_vdwa_f = k_vdwa = cutoff6 / ( cutoff6 - switchOn6 );
535  k_vdwb_f = k_vdwb = cutoff3 / ( cutoff3 - switchOn3 );
536  cutoff_3_f = cutoff_3 = 1. / cutoff3;
537  cutoff_6_f = cutoff_6 = 1. / cutoff6;
538 
539  } else if ( simParams->martiniSwitching ) { // switching fxn for Martini RBCG
540 
541  BigReal p6 = 6;
542  BigReal A6 = p6 * ((p6+1)*switchOn-(p6+4)*cutoff)/(pow(cutoff,p6+2)*pow(cutoff-switchOn,2));
543  BigReal B6 = -p6 * ((p6+1)*switchOn-(p6+3)*cutoff)/(pow(cutoff,p6+2)*pow(cutoff-switchOn,3));
544  BigReal C6 = 1.0/pow(cutoff,p6)-A6/3.0*pow(cutoff-switchOn,3)-B6/4.0*pow(cutoff-switchOn,4);
545 
546  BigReal p12 = 12;
547  BigReal A12 = p12 * ((p12+1)*switchOn-(p12+4)*cutoff)/(pow(cutoff,p12+2)*pow(cutoff-switchOn,2));
548  BigReal B12 = -p12 * ((p12+1)*switchOn-(p12+3)*cutoff)/(pow(cutoff,p12+2)*pow(cutoff-switchOn,3));
549  BigReal C12 = 1.0/pow(cutoff,p12)-A12/3.0*pow(cutoff-switchOn,3)-B12/4.0*pow(cutoff-switchOn,4);
550 
551  A6_f = A6; B6_f = B6; C6_f = C6;
552  A12_f = A12; B12_f = B12; C12_f = C12;
554 
555  }
556 
557  }
558  else
559  {
560  switchOn = cutoff;
561  switchOn_1 = 1.0/switchOn;
562  // d0 = 0.; // avoid division by zero
564  c0 = 0.; // avoid division by zero
565  }
566  c1 = c0*c0*c0;
567  c3 = 3.0 * (cutoff2 - switchOn2);
568  c5 = 0;
569  c6 = 0;
570  c7 = 0;
571  c8 = 0;
572 
573  const int PMEOn = simParams->PMEOn;
574  const int MSMOn = simParams->MSMOn;
575  const int MSMSplit = simParams->MSMSplit;
576 
577  if ( PMEOn ) {
578  ewaldcof = simParams->PMEEwaldCoefficient;
579  BigReal TwoBySqrtPi = 1.12837916709551;
580  pi_ewaldcof = TwoBySqrtPi * ewaldcof;
581  }
582 
583  int splitType = SPLIT_NONE;
584  if ( simParams->switchingActive ) splitType = SPLIT_SHIFT;
585  if ( simParams->martiniSwitching ) splitType = SPLIT_MARTINI;
586  if ( simParams->fullDirectOn || simParams->FMAOn || PMEOn || MSMOn ||
587  simParams->FMMOn ) {
588  switch ( simParams->longSplitting ) {
589  case C2:
590  splitType = SPLIT_C2;
591  break;
592 
593  case C1:
594  splitType = SPLIT_C1;
595  break;
596 
597  case XPLOR:
598  NAMD_die("Sorry, XPLOR splitting not supported.");
599  break;
600 
601  case SHARP:
602  NAMD_die("Sorry, SHARP splitting not supported.");
603  break;
604 
605  default:
606  NAMD_die("Unknown splitting type found!");
607 
608  }
609  }
610 
611  BigReal r2_tol = 0.1;
612 
613  r2_delta = 1.0;
614  r2_delta_exp = 0;
615  while ( r2_delta > r2_tol ) { r2_delta /= 2.0; r2_delta_exp += 1; }
616  r2_delta_1 = 1.0 / r2_delta;
617 
618  if ( ! CkMyPe() ) {
619  iout << iINFO << "NONBONDED TABLE R-SQUARED SPACING: " <<
620  r2_delta << "\n" << endi;
621  }
622 
623  BigReal r2_tmp = 1.0;
624  int cutoff2_exp = 0;
625  while ( (cutoff2 + r2_delta) > r2_tmp ) { r2_tmp *= 2.0; cutoff2_exp += 1; }
626 
627  int i;
628  int n = (r2_delta_exp + cutoff2_exp) * 64 + 1;
629  table_length = n;
630  #if defined(NAMD_MIC)
631  int n_16 = (n + 15) & (~15);
632  #endif
633 
634  if ( ! CkMyPe() ) {
635  iout << iINFO << "NONBONDED TABLE SIZE: " <<
636  n << " POINTS\n" << endi;
637  }
638 
639  if ( table_alloc ) delete [] table_alloc;
640  #if defined(NAMD_MIC)
641  table_alloc = new BigReal[61*n_16+16];
642  BigReal *table_align = table_alloc;
643  while ( ((long)table_align) % 128 ) ++table_align;
644  mic_table_base_ptr = table_align;
645  mic_table_n = n;
646  mic_table_n_16 = n_16;
647  table_noshort = table_align;
648  table_short = table_align + 16*n_16;
649  slow_table = table_align + 32*n_16;
650  fast_table = table_align + 36*n_16;
651  scor_table = table_align + 40*n_16;
652  corr_table = table_align + 44*n_16;
653  full_table = table_align + 48*n_16;
654  vdwa_table = table_align + 52*n_16;
655  vdwb_table = table_align + 56*n_16;
656  r2_table = table_align + 60*n_16;
657  #else
658  table_alloc = new BigReal[61*n+16];
659  BigReal *table_align = table_alloc;
660  while ( ((long)table_align) % 128 ) ++table_align;
661  table_noshort = table_align;
662  table_short = table_align + 16*n;
663  slow_table = table_align + 32*n;
664  fast_table = table_align + 36*n;
665  scor_table = table_align + 40*n;
666  corr_table = table_align + 44*n;
667  full_table = table_align + 48*n;
668  vdwa_table = table_align + 52*n;
669  vdwb_table = table_align + 56*n;
670  r2_table = table_align + 60*n;
671  #endif
672  BigReal *fast_i = fast_table + 4;
673  BigReal *scor_i = scor_table + 4;
674  BigReal *slow_i = slow_table + 4;
675  BigReal *vdwa_i = vdwa_table + 4;
676  BigReal *vdwb_i = vdwb_table + 4;
677  BigReal *r2_i = r2_table; *(r2_i++) = r2_delta;
678  BigReal r2_limit = simParams->limitDist * simParams->limitDist;
679  if ( r2_limit < r2_delta ) r2_limit = r2_delta;
680  int r2_delta_i = 0; // entry for r2 == r2_delta
681 
682 #ifdef NAMD_AVXTILES
683  {
684  avxTilesMode = 1;
685  if (!simParams->useAVXTiles)
686  avxTilesMode = 0;
687  if (avxTilesMode) {
688  if (simParams->vdwGeometricSigma) avxTilesMode = 2;
689  if ( simParams->fullDirectOn || simParams->FMAOn || PMEOn || MSMOn ||
690  simParams->FMMOn ) {
691  if ( simParams->longSplitting != C1)
692  avxTilesMode = 3;
693  } else
694  avxTilesMode = 3;
695  if (avxTilesMode == 1) {
696  const int table_dim = ljTable->get_table_dim();
697  Real A, B, A14, B14;
698  for (int i = 0; i < table_dim; i++)
699  for (int j = i+1; j < table_dim; j++)
700  if (params->get_vdw_pair_params(i, j, &A, &B, &A14, &B14))
701  avxTilesMode = 2;
702  }
703  if (avxTilesMode > 1)
704  iout << iINFO << "AVX-512 TILES WILL USE SHORT-RANGE INTERPOLATION ("
705  << avxTilesMode << ")\n";
706  else {
707  Parameters *params = Node::Object()->parameters;
708  const int num_params = params->get_num_vdw_params();
709  if ( avx_tiles_eps4_sigma ) delete [] avx_tiles_eps4_sigma;
710  if ( avx_tiles_eps4_sigma_14 ) delete [] avx_tiles_eps4_sigma_14;
711  avx_tiles_eps4_sigma = new float[num_params*2];
712  avx_tiles_eps4_sigma_14 = new float[num_params*2];
713  for (int i = 0; i < num_params; i++) {
714  Real sigma, sigma_14, epsilon, epsilon_14;
715  params->get_vdw_params(&sigma, &epsilon, &sigma_14,
716  &epsilon_14,i);
717  // Set the epsilon and epsilon_14 to zero if we do LJ-PME
718 //if (simParams->LJPMESerial) {
719  if (simParams->LJPMEOn) {
720  epsilon = epsilon_14 = 0.0;
721  }
722 //}
723  avx_tiles_eps4_sigma[i*2] = 4.0 * scaling * epsilon;
724  avx_tiles_eps4_sigma[i*2 + 1] = sigma;
725  avx_tiles_eps4_sigma_14[i*2] = 4.0 * scaling * epsilon_14;
726  avx_tiles_eps4_sigma_14[i*2 + 1] = sigma_14;
727  }
728  }
729  }
730  }
731 #endif
732 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
733  if ( knl_table_alloc ) delete [] knl_table_alloc;
734  if ( KNL_TABLE_MAX_R_1 < 1.f || KNL_TABLE_FACTOR < 1 ||
735  KNL_TABLE_FACTOR !=
736  static_cast<int>(1.0 / KNL_TABLE_MAX_R_1 * KNL_TABLE_SIZE))
737  NAMD_bug("Inconsistent KNL preprocessor settings.");
738 #ifdef NAMD_KNL
739  knl_table_alloc = new float[10*KNL_TABLE_SIZE];
740 #else
741  knl_table_alloc = new float[8*KNL_TABLE_SIZE];
742 #endif
743  knl_fast_ener_table = knl_table_alloc;
744  knl_fast_grad_table = knl_table_alloc + KNL_TABLE_SIZE;
745  knl_scor_ener_table = knl_table_alloc + 2*KNL_TABLE_SIZE;
746  knl_scor_grad_table = knl_table_alloc + 3*KNL_TABLE_SIZE;
747  knl_slow_ener_table = knl_table_alloc + 4*KNL_TABLE_SIZE;
748  knl_slow_grad_table = knl_table_alloc + 5*KNL_TABLE_SIZE;
749  knl_excl_ener_table = knl_table_alloc + 6*KNL_TABLE_SIZE;
750  knl_excl_grad_table = knl_table_alloc + 7*KNL_TABLE_SIZE;
751  knl_fast_ener_table[0] = 0.;
752  knl_fast_grad_table[0] = 0.;
753  knl_scor_ener_table[0] = 0.;
754  knl_scor_grad_table[0] = 0.;
755  knl_slow_ener_table[0] = 0.;
756  knl_slow_grad_table[0] = 0.;
757  knl_excl_ener_table[0] = 0.;
758  knl_excl_grad_table[0] = 0.;
759 #ifdef NAMD_KNL
760  knl_corr_ener_table = knl_table_alloc + 8*KNL_TABLE_SIZE;
761  knl_corr_grad_table = knl_table_alloc + 9*KNL_TABLE_SIZE;
762  knl_corr_ener_table[0] = 0.;
763  knl_corr_grad_table[0] = 0.;
764 #endif
765  for ( int knl_table = 0; knl_table < 2; ++knl_table ) {
766  int nn = n;
767  if ( knl_table ) {
768  nn = KNL_TABLE_SIZE-1;
769  }
770  for ( i=1; i<nn; ++i ) {
771 #else
772  // fill in the table, fix up i==0 (r2==0) below
773  for ( i=1; i<n; ++i ) {
774 #endif
775 
776  const BigReal r2_base = r2_delta * ( 1 << (i/64) );
777  const BigReal r2_del = r2_base / 64.0;
778  BigReal r2 = r2_base - r2_delta + r2_del * (i%64);
779 
780  BigReal r = sqrt(r2);
781 
782 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
783  if ( knl_table ) {
784  r = (double)(KNL_TABLE_FACTOR-2)/(double)(i);
785  r2 = r*r;
786  } else
787 #endif
788  if ( r2 <= r2_limit ) r2_delta_i = i;
789 
790  const BigReal r_1 = 1.0/r;
791  const BigReal r_2 = 1.0/r2;
792 
793  // fast_ is defined as (full_ - slow_)
794  // corr_ and fast_ are both zero at the cutoff, full_ is not
795  // all three are approx 1/r at short distances
796 
797  // for actual interpolation, we use fast_ for fast forces and
798  // scor_ = slow_ + corr_ - full_ and slow_ for slow forces
799  // since these last two are of small magnitude
800 
801  BigReal fast_energy, fast_gradient;
802  BigReal scor_energy, scor_gradient;
803  BigReal slow_energy, slow_gradient;
804 
805  // corr_ is PME direct sum, or similar correction term
806  // corr_energy is multiplied by r until later
807  // corr_gradient is multiplied by -r^2 until later
808  BigReal corr_energy, corr_gradient;
809 
810 
811  if ( PMEOn ) {
812  BigReal tmp_a = r * ewaldcof;
813  BigReal tmp_b = erfc(tmp_a);
814  corr_energy = tmp_b;
815  corr_gradient = pi_ewaldcof*exp(-(tmp_a*tmp_a))*r + tmp_b;
816  } else if ( MSMOn ) {
817  BigReal a_1 = 1.0/cutoff;
818  BigReal r_a = r * a_1;
819  BigReal g, dg;
820  SPOLY(&g, &dg, r_a, MSMSplit);
821  corr_energy = 1 - r_a * g;
822  corr_gradient = 1 + r_a*r_a * dg;
823  } else {
824  corr_energy = corr_gradient = 0;
825  }
826 
827  switch(splitType) {
828  case SPLIT_NONE:
829  fast_energy = 1.0/r;
830  fast_gradient = -1.0/r2;
831  scor_energy = scor_gradient = 0;
832  slow_energy = slow_gradient = 0;
833  break;
834  case SPLIT_SHIFT: {
835  BigReal shiftVal = r2/cutoff2 - 1.0;
836  shiftVal *= shiftVal;
837  BigReal dShiftVal = 2.0 * (r2/cutoff2 - 1.0) * 2.0*r/cutoff2;
838  fast_energy = shiftVal/r;
839  fast_gradient = dShiftVal/r - shiftVal/r2;
840  scor_energy = scor_gradient = 0;
841  slow_energy = slow_gradient = 0;
842  }
843  break;
844  case SPLIT_MARTINI: {
845  // in Martini, the Coulomb switching distance is zero
846  const BigReal COUL_SWITCH = 0.;
847  // Gromacs shifting function
848  const BigReal p1 = 1.;
849  BigReal A1 = p1 * ((p1+1)*COUL_SWITCH-(p1+4)*cutoff)/(pow(cutoff,p1+2)*pow(cutoff-COUL_SWITCH,2));
850  BigReal B1 = -p1 * ((p1+1)*COUL_SWITCH-(p1+3)*cutoff)/(pow(cutoff,p1+2)*pow(cutoff-COUL_SWITCH,3));
851  BigReal X1 = 1.0/pow(cutoff,p1)-A1/3.0*pow(cutoff-COUL_SWITCH,3)-B1/4.0*pow(cutoff-COUL_SWITCH,4);
852  BigReal r12 = (r-COUL_SWITCH)*(r-COUL_SWITCH);
853  BigReal r13 = (r-COUL_SWITCH)*(r-COUL_SWITCH)*(r-COUL_SWITCH);
854  BigReal shiftVal = -(A1/3.0)*r13 - (B1/4.0)*r12*r12 - X1;
855  BigReal dShiftVal = -A1*r12 - B1*r13;
856  fast_energy = (1/r) + shiftVal;
857  fast_gradient = -1/(r2) + dShiftVal;
858  scor_energy = scor_gradient = 0;
859  slow_energy = slow_gradient = 0;
860  }
861  break;
862  case SPLIT_C1:
863  // calculate actual energy and gradient
864  slow_energy = 0.5/cutoff * (3.0 - (r2/cutoff2));
865  slow_gradient = -1.0/cutoff2 * (r/cutoff);
866  // calculate scor from slow and corr
867  scor_energy = slow_energy + (corr_energy - 1.0)/r;
868  scor_gradient = slow_gradient - (corr_gradient - 1.0)/r2;
869  // calculate fast from slow
870  fast_energy = 1.0/r - slow_energy;
871  fast_gradient = -1.0/r2 - slow_gradient;
872  break;
873  case SPLIT_C2:
874  //
875  // Quintic splitting function contributed by
876  // Bruce Berne, Ruhong Zhou, and Joe Morrone
877  //
878  // calculate actual energy and gradient
879  slow_energy = r2/(cutoff*cutoff2) * (6.0 * (r2/cutoff2)
880  - 15.0*(r/cutoff) + 10.0);
881  slow_gradient = r/(cutoff*cutoff2) * (24.0 * (r2/cutoff2)
882  - 45.0 *(r/cutoff) + 20.0);
883  // calculate scor from slow and corr
884  scor_energy = slow_energy + (corr_energy - 1.0)/r;
885  scor_gradient = slow_gradient - (corr_gradient - 1.0)/r2;
886  // calculate fast from slow
887  fast_energy = 1.0/r - slow_energy;
888  fast_gradient = -1.0/r2 - slow_gradient;
889  break;
890  }
891 
892  // foo_gradient is calculated as ( d foo_energy / d r )
893  // and now divided by 2r to get ( d foo_energy / d r2 )
894 
895  fast_gradient *= 0.5 * r_1;
896  scor_gradient *= 0.5 * r_1;
897  slow_gradient *= 0.5 * r_1;
898 
899  // let modf be 1 if excluded, 1-scale14 if modified, 0 otherwise,
900  // add scor_ - modf * slow_ to slow terms and
901  // add fast_ - modf * fast_ to fast terms.
902 
903  BigReal vdwa_energy, vdwa_gradient;
904  BigReal vdwb_energy, vdwb_gradient;
905 
906  const BigReal r_6 = r_2*r_2*r_2;
907  const BigReal r_12 = r_6*r_6;
908 
909  // Lennard-Jones switching function
910  if ( simParams->vdwForceSwitching ) { // switch force
912 
913  // from Steinbach & Brooks, JCC 15, pgs 667-683, 1994, eqns 10-13
914  if ( r2 > switchOn2 ) {
915  BigReal tmpa = r_6 - cutoff_6;
916  vdwa_energy = k_vdwa * tmpa * tmpa;
917  BigReal tmpb = r_1 * r_2 - cutoff_3;
918  vdwb_energy = k_vdwb * tmpb * tmpb;
919  vdwa_gradient = -6.0 * k_vdwa * tmpa * r_2 * r_6;
920  vdwb_gradient = -3.0 * k_vdwb * tmpb * r_2 * r_2 * r_1;
921  } else {
922  vdwa_energy = r_12 + v_vdwa;
923  vdwb_energy = r_6 + v_vdwb;
924  vdwa_gradient = -6.0 * r_2 * r_12;
925  vdwb_gradient = -3.0 * r_2 * r_6;
926  }
927  } else if ( simParams->martiniSwitching ) { // switching fxn for Martini RBCG
929 
930  BigReal r12 = (r-switchOn)*(r-switchOn); BigReal r13 = (r-switchOn)*(r-switchOn)*(r-switchOn);
931 
932  BigReal p6 = 6;
933  BigReal A6 = p6 * ((p6+1)*switchOn-(p6+4)*cutoff)/(pow(cutoff,p6+2)*pow(cutoff-switchOn,2));
934  BigReal B6 = -p6 * ((p6+1)*switchOn-(p6+3)*cutoff)/(pow(cutoff,p6+2)*pow(cutoff-switchOn,3));
935  BigReal C6 = 1.0/pow(cutoff,p6)-A6/3.0*pow(cutoff-switchOn,3)-B6/4.0*pow(cutoff-switchOn,4);
936 
937  BigReal p12 = 12;
938  BigReal A12 = p12 * ((p12+1)*switchOn-(p12+4)*cutoff)/(pow(cutoff,p12+2)*pow(cutoff-switchOn,2));
939  BigReal B12 = -p12 * ((p12+1)*switchOn-(p12+3)*cutoff)/(pow(cutoff,p12+2)*pow(cutoff-switchOn,3));
940  BigReal C12 = 1.0/pow(cutoff,p12)-A12/3.0*pow(cutoff-switchOn,3)-B12/4.0*pow(cutoff-switchOn,4);
941 
942  BigReal LJshifttempA = -(A12/3)*r13 - (B12/4)*r12*r12 - C12;
943  BigReal LJshifttempB = -(A6/3)*r13 - (B6/4)*r12*r12 - C6;
944  const BigReal shiftValA = // used for Lennard-Jones
945  ( r2 > switchOn2 ? LJshifttempA : -C12);
946  const BigReal shiftValB = // used for Lennard-Jones
947  ( r2 > switchOn2 ? LJshifttempB : -C6);
948 
949  BigReal LJdshifttempA = -A12*r12 - B12*r13;
950  BigReal LJdshifttempB = -A6*r12 - B6*r13;
951  const BigReal dshiftValA = // used for Lennard-Jones
952  ( r2 > switchOn2 ? LJdshifttempA*0.5*r_1 : 0 );
953  const BigReal dshiftValB = // used for Lennard-Jones
954  ( r2 > switchOn2 ? LJdshifttempB*0.5*r_1 : 0 );
955 
956 
957 
958 
959  //have not addressed r > cutoff
960 
961  // dshiftValA*= 0.5*r_1;
962  // dshiftValB*= 0.5*r_1;
963 
964  vdwa_energy = r_12 + shiftValA;
965  vdwb_energy = r_6 + shiftValB;
966 
967  vdwa_gradient = -6/pow(r,14) + dshiftValA ;
968  vdwb_gradient = -3/pow(r,8) + dshiftValB;
969 
970  } else { // switch energy
972 
973  const BigReal c2 = cutoff2-r2;
974  const BigReal c4 = c2*(c3-2.0*c2);
975  const BigReal switchVal = // used for Lennard-Jones
976  ( r2 > switchOn2 ? c2*c4*c1 : 1.0 );
977  const BigReal dSwitchVal = // d switchVal / d r2
978  ( r2 > switchOn2 ? 2*c1*(c2*c2-c4) : 0.0 );
979 
980  vdwa_energy = switchVal * r_12;
981  vdwb_energy = switchVal * r_6;
982 
983  vdwa_gradient = ( dSwitchVal - 6.0 * switchVal * r_2 ) * r_12;
984  vdwb_gradient = ( dSwitchVal - 3.0 * switchVal * r_2 ) * r_6;
985  }
986 
987 
988 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
989  if ( knl_table ) {
990  knl_fast_ener_table[i] = -1.*fast_energy;
991  knl_fast_grad_table[i] = -2.*fast_gradient;
992  knl_scor_ener_table[i] = -1.*scor_energy;
993  knl_scor_grad_table[i] = -2.*scor_gradient;
994  knl_slow_ener_table[i] = (-1.*scor_energy - (scale14-1)*slow_energy) /
995  scale14;
996  knl_slow_grad_table[i] = (-2.*scor_gradient -
997  (scale14-1)*2.*slow_gradient) / scale14;
998  knl_excl_ener_table[i] = slow_energy - scor_energy;
999  knl_excl_grad_table[i] = 2.*(slow_gradient - scor_gradient);
1000 #ifdef NAMD_KNL
1001  knl_corr_ener_table[i] = -1.*(fast_energy + scor_energy);
1002  knl_corr_grad_table[i] = -2.*(fast_gradient + scor_gradient);
1003 #endif
1004  if ( i == nn-1 ) {
1005  knl_fast_ener_table[nn] = knl_fast_ener_table[i];
1006  knl_fast_grad_table[nn] = knl_fast_grad_table[i];
1007  knl_scor_ener_table[nn] = knl_scor_ener_table[i];
1008  knl_scor_grad_table[nn] = knl_scor_grad_table[i];
1009  knl_slow_ener_table[nn] = knl_slow_ener_table[i];
1010  knl_slow_grad_table[nn] = knl_slow_grad_table[i];
1011  knl_excl_ener_table[nn] = knl_excl_ener_table[i];
1012  knl_excl_grad_table[nn] = knl_excl_grad_table[i];
1013 #ifdef NAMD_KNL
1014  knl_corr_ener_table[nn] = knl_corr_ener_table[i];
1015  knl_corr_grad_table[nn] = knl_corr_grad_table[i];
1016 #endif
1017  }
1018  } else {
1019 #endif
1020  *(fast_i++) = fast_energy;
1021  *(fast_i++) = fast_gradient;
1022  *(fast_i++) = 0;
1023  *(fast_i++) = 0;
1024  *(scor_i++) = scor_energy;
1025  *(scor_i++) = scor_gradient;
1026  *(scor_i++) = 0;
1027  *(scor_i++) = 0;
1028  *(slow_i++) = slow_energy;
1029  *(slow_i++) = slow_gradient;
1030  *(slow_i++) = 0;
1031  *(slow_i++) = 0;
1032  *(vdwa_i++) = vdwa_energy;
1033  *(vdwa_i++) = vdwa_gradient;
1034  *(vdwa_i++) = 0;
1035  *(vdwa_i++) = 0;
1036  *(vdwb_i++) = vdwb_energy;
1037  *(vdwb_i++) = vdwb_gradient;
1038  *(vdwb_i++) = 0;
1039  *(vdwb_i++) = 0;
1040  *(r2_i++) = r2 + r2_delta;
1041 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
1042  }
1043 #endif
1044 
1045  }
1046 #if defined(NAMD_KNL) || defined(NAMD_AVXTILES)
1047  } // knl_table loop
1048 #endif
1049 
1050  if ( ! r2_delta_i ) {
1051  NAMD_bug("Failed to find table entry for r2 == r2_limit\n");
1052  }
1053  if ( r2_table[r2_delta_i] > r2_limit + r2_delta ) {
1054  NAMD_bug("Found bad table entry for r2 == r2_limit\n");
1055  }
1056 
1057  int j;
1058  const char *table_name = "XXXX";
1059  int smooth_short = 0;
1060  for ( j=0; j<5; ++j ) {
1061  BigReal *t0 = 0;
1062  switch (j) {
1063  case 0:
1064  t0 = fast_table;
1065  table_name = "FAST";
1066  smooth_short = 1;
1067  break;
1068  case 1:
1069  t0 = scor_table;
1070  table_name = "SCOR";
1071  smooth_short = 0;
1072  break;
1073  case 2:
1074  t0 = slow_table;
1075  table_name = "SLOW";
1076  smooth_short = 0;
1077  break;
1078  case 3:
1079  t0 = vdwa_table;
1080  table_name = "VDWA";
1081  smooth_short = 1;
1082  break;
1083  case 4:
1084  t0 = vdwb_table;
1085  table_name = "VDWB";
1086  smooth_short = 1;
1087  break;
1088  }
1089  // patch up data for i=0
1090  t0[0] = t0[4] - t0[5] * ( r2_delta / 64.0 ); // energy
1091  t0[1] = t0[5]; // gradient
1092  t0[2] = 0;
1093  t0[3] = 0;
1094  if ( smooth_short ) {
1095  BigReal energy0 = t0[4*r2_delta_i];
1096  BigReal gradient0 = t0[4*r2_delta_i+1];
1097  BigReal r20 = r2_table[r2_delta_i];
1098  t0[0] = energy0 - gradient0 * (r20 - r2_table[0]); // energy
1099  t0[1] = gradient0; // gradient
1100  }
1101  BigReal *t;
1102  for ( i=0,t=t0; i<(n-1); ++i,t+=4 ) {
1103  BigReal x = ( r2_delta * ( 1 << (i/64) ) ) / 64.0;
1104  if ( r2_table[i+1] != r2_table[i] + x ) {
1105  NAMD_bug("Bad table delta calculation.\n");
1106  }
1107  if ( smooth_short && i+1 < r2_delta_i ) {
1108  BigReal energy0 = t0[4*r2_delta_i];
1109  BigReal gradient0 = t0[4*r2_delta_i+1];
1110  BigReal r20 = r2_table[r2_delta_i];
1111  t[4] = energy0 - gradient0 * (r20 - r2_table[i+1]); // energy
1112  t[5] = gradient0; // gradient
1113  }
1114  BigReal v1 = t[0];
1115  BigReal g1 = t[1];
1116  BigReal v2 = t[4];
1117  BigReal g2 = t[5];
1118  // explicit formulas for v1 + g1 x + c x^2 + d x^3
1119  BigReal c = ( 3.0 * (v2 - v1) - x * (2.0 * g1 + g2) ) / ( x * x );
1120  BigReal d = ( -2.0 * (v2 - v1) + x * (g1 + g2) ) / ( x * x * x );
1121  // since v2 - v1 is imprecise, we refine c and d numerically
1122  // important because we need accurate forces (more than energies!)
1123  for ( int k=0; k < 2; ++k ) {
1124  BigReal dv = (v1 - v2) + ( ( d * x + c ) * x + g1 ) * x;
1125  BigReal dg = (g1 - g2) + ( 3.0 * d * x + 2.0 * c ) * x;
1126  c -= ( 3.0 * dv - x * dg ) / ( x * x );
1127  d -= ( -2.0 * dv + x * dg ) / ( x * x * x );
1128  }
1129  // store in the array;
1130  t[2] = c; t[3] = d;
1131  }
1132 
1133  if ( ! CkMyPe() ) {
1134  BigReal dvmax = 0;
1135  BigReal dgmax = 0;
1136  BigReal dvmax_r = 0;
1137  BigReal dgmax_r = 0;
1138  BigReal fdvmax = 0;
1139  BigReal fdgmax = 0;
1140  BigReal fdvmax_r = 0;
1141  BigReal fdgmax_r = 0;
1142  BigReal dgcdamax = 0;
1143  BigReal dgcdimax = 0;
1144  BigReal dgcaimax = 0;
1145  BigReal dgcdamax_r = 0;
1146  BigReal dgcdimax_r = 0;
1147  BigReal dgcaimax_r = 0;
1148  BigReal fdgcdamax = 0;
1149  BigReal fdgcdimax = 0;
1150  BigReal fdgcaimax = 0;
1151  BigReal fdgcdamax_r = 0;
1152  BigReal fdgcdimax_r = 0;
1153  BigReal fdgcaimax_r = 0;
1154  BigReal gcm = fabs(t0[1]); // gradient magnitude running average
1155  for ( i=0,t=t0; i<(n-1); ++i,t+=4 ) {
1156  const BigReal r2_base = r2_delta * ( 1 << (i/64) );
1157  const BigReal r2_del = r2_base / 64.0;
1158  const BigReal r2 = r2_base - r2_delta + r2_del * (i%64);
1159  const BigReal r = sqrt(r2);
1160  if ( r > cutoff ) break;
1161  BigReal x = r2_del;
1162  BigReal dv = ( ( t[3] * x + t[2] ) * x + t[1] ) * x + t[0] - t[4];
1163  BigReal dg = ( 3.0 * t[3] * x + 2.0 * t[2] ) * x + t[1] - t[5];
1164  if ( t[4] != 0. && fabs(dv/t[4]) > fdvmax ) {
1165  fdvmax = fabs(dv/t[4]); fdvmax_r = r;
1166  }
1167  if ( fabs(dv) > dvmax ) {
1168  dvmax = fabs(dv); dvmax_r = r;
1169  }
1170  if ( t[5] != 0. && fabs(dg/t[5]) > fdgmax ) {
1171  fdgmax = fabs(dg/t[5]); fdgmax_r = r;
1172  }
1173  if ( fabs(dg) > dgmax ) {
1174  dgmax = fabs(dg); dgmax_r = r;
1175  }
1176  BigReal gcd = (t[4] - t[0]) / x; // centered difference gradient
1177  BigReal gcd_prec = (fabs(t[0]) + fabs(t[4])) * 1.e-15 / x; // roundoff
1178  gcm = 0.9 * gcm + 0.1 * fabs(t[5]); // magnitude running average
1179  BigReal gca = 0.5 * (t[1] + t[5]); // centered average gradient
1180  BigReal gci = ( 0.75 * t[3] * x + t[2] ) * x + t[1]; // interpolated
1181  BigReal rc = sqrt(r2 + 0.5 * x);
1182  BigReal dgcda = gcd - gca;
1183  if ( dgcda != 0. && fabs(dgcda) < gcd_prec ) {
1184  // CkPrintf("ERROR %g < PREC %g AT %g AVG VAL %g\n", dgcda, gcd_prec, rc, gca);
1185  dgcda = 0.;
1186  }
1187  BigReal dgcdi = gcd - gci;
1188  if ( dgcdi != 0. && fabs(dgcdi) < gcd_prec ) {
1189  // CkPrintf("ERROR %g < PREC %g AT %g INT VAL %g\n", dgcdi, gcd_prec, rc, gci);
1190  dgcdi = 0.;
1191  }
1192  BigReal dgcai = gca - gci;
1193  if ( t[1]*t[5] > 0. && gcm != 0. && fabs(dgcda/gcm) > fdgcdamax ) {
1194  fdgcdamax = fabs(dgcda/gcm); fdgcdamax_r = rc;
1195  }
1196  if ( fabs(dgcda) > fdgcdamax ) {
1197  dgcdamax = fabs(dgcda); dgcdamax_r = rc;
1198  }
1199  if ( t[1]*t[5] > 0. && gcm != 0. && fabs(dgcdi/gcm) > fdgcdimax ) {
1200  fdgcdimax = fabs(dgcdi/gcm); fdgcdimax_r = rc;
1201  }
1202  if ( fabs(dgcdi) > fdgcdimax ) {
1203  dgcdimax = fabs(dgcdi); dgcdimax_r = rc;
1204  }
1205  if ( t[1]*t[5] > 0. && gcm != 0. && fabs(dgcai/gcm) > fdgcaimax ) {
1206  fdgcaimax = fabs(dgcai/gcm); fdgcaimax_r = rc;
1207  }
1208  if ( fabs(dgcai) > fdgcaimax ) {
1209  dgcaimax = fabs(dgcai); dgcaimax_r = rc;
1210  }
1211 #if 0
1212  CkPrintf("TABLE %s %g %g %g %g\n",table_name,rc,dgcda/gcm,dgcda,gci);
1213  if (dv != 0.) CkPrintf("TABLE %d ENERGY ERROR %g AT %g (%d)\n",j,dv,r,i);
1214  if (dg != 0.) CkPrintf("TABLE %d FORCE ERROR %g AT %g (%d)\n",j,dg,r,i);
1215 #endif
1216  }
1217  if ( dvmax != 0.0 ) {
1218  iout << iINFO << "ABSOLUTE IMPRECISION IN " << table_name <<
1219  " TABLE ENERGY: " << dvmax << " AT " << dvmax_r << "\n" << endi;
1220  }
1221  if ( fdvmax != 0.0 ) {
1222  iout << iINFO << "RELATIVE IMPRECISION IN " << table_name <<
1223  " TABLE ENERGY: " << fdvmax << " AT " << fdvmax_r << "\n" << endi;
1224  }
1225  if ( dgmax != 0.0 ) {
1226  iout << iINFO << "ABSOLUTE IMPRECISION IN " << table_name <<
1227  " TABLE FORCE: " << dgmax << " AT " << dgmax_r << "\n" << endi;
1228  }
1229  if ( fdgmax != 0.0 ) {
1230  iout << iINFO << "RELATIVE IMPRECISION IN " << table_name <<
1231  " TABLE FORCE: " << fdgmax << " AT " << fdgmax_r << "\n" << endi;
1232  }
1233  if (fdgcdamax != 0.0 ) {
1234  iout << iINFO << "INCONSISTENCY IN " << table_name <<
1235  " TABLE ENERGY VS FORCE: " << fdgcdamax << " AT " << fdgcdamax_r << "\n" << endi;
1236  if ( fdgcdamax > 0.1 ) {
1237  iout << iERROR << "\n";
1238  iout << iERROR << "CALCULATED " << table_name <<
1239  " FORCE MAY NOT MATCH ENERGY! POSSIBLE BUG!\n";
1240  iout << iERROR << "\n";
1241  }
1242  }
1243  if (0 && fdgcdimax != 0.0 ) {
1244  iout << iINFO << "INCONSISTENCY IN " << table_name <<
1245  " TABLE ENERGY VS FORCE: " << fdgcdimax << " AT " << fdgcdimax_r << "\n" << endi;
1246  }
1247  if ( 0 && fdgcaimax != 0.0 ) {
1248  iout << iINFO << "INCONSISTENCY IN " << table_name <<
1249  " TABLE AVG VS INT FORCE: " << fdgcaimax << " AT " << fdgcaimax_r << "\n" << endi;
1250  }
1251  }
1252 
1253  }
1254 
1255  for ( i=0; i<4*n; ++i ) {
1256  corr_table[i] = fast_table[i] + scor_table[i];
1257  full_table[i] = fast_table[i] + slow_table[i];
1258  }
1259 
1260 #if 0
1261  for ( i=0; i<n; ++i ) {
1262  for ( int j=0; j<4; ++j ) {
1263  table_short[16*i+6-2*j] = table_noshort[16*i+6-2*j] = vdwa_table[4*i+j];
1264  table_short[16*i+7-2*j] = table_noshort[16*i+7-2*j] = vdwb_table[4*i+j];
1265  table_short[16*i+8+3-j] = fast_table[4*i+j];
1266  table_short[16*i+12+3-j] = scor_table[4*i+j];
1267  table_noshort[16*i+8+3-j] = corr_table[4*i+j];
1268  table_noshort[16*i+12+3-j] = full_table[4*i+j];
1269  }
1270  }
1271 #endif
1272 
1273  for ( i=0; i<n; ++i ) {
1274  table_short[16*i+0] = table_noshort[16*i+0] = -6.*vdwa_table[4*i+3];
1275  table_short[16*i+1] = table_noshort[16*i+1] = -4.*vdwa_table[4*i+2];
1276  table_short[16*i+2] = table_noshort[16*i+2] = -2.*vdwa_table[4*i+1];
1277  table_short[16*i+3] = table_noshort[16*i+3] = -1.*vdwa_table[4*i+0];
1278 
1279  table_short[16*i+4] = table_noshort[16*i+4] = -6.*vdwb_table[4*i+3];
1280  table_short[16*i+5] = table_noshort[16*i+5] = -4.*vdwb_table[4*i+2];
1281  table_short[16*i+6] = table_noshort[16*i+6] = -2.*vdwb_table[4*i+1];
1282  table_short[16*i+7] = table_noshort[16*i+7] = -1.*vdwb_table[4*i+0];
1283 
1284  table_short[16*i+8] = -6.*fast_table[4*i+3];
1285  table_short[16*i+9] = -4.*fast_table[4*i+2];
1286  table_short[16*i+10] = -2.*fast_table[4*i+1];
1287  table_short[16*i+11] = -1.*fast_table[4*i+0];
1288 
1289  table_noshort[16*i+8] = -6.*corr_table[4*i+3];
1290  table_noshort[16*i+9] = -4.*corr_table[4*i+2];
1291  table_noshort[16*i+10] = -2.*corr_table[4*i+1];
1292  table_noshort[16*i+11] = -1.*corr_table[4*i+0];
1293 
1294  table_short[16*i+12] = -6.*scor_table[4*i+3];
1295  table_short[16*i+13] = -4.*scor_table[4*i+2];
1296  table_short[16*i+14] = -2.*scor_table[4*i+1];
1297  table_short[16*i+15] = -1.*scor_table[4*i+0];
1298 
1299  table_noshort[16*i+12] = -6.*full_table[4*i+3];
1300  table_noshort[16*i+13] = -4.*full_table[4*i+2];
1301  table_noshort[16*i+14] = -2.*full_table[4*i+1];
1302  table_noshort[16*i+15] = -1.*full_table[4*i+0];
1303  }
1304 
1305 #if 0
1306  char fname[100];
1307  sprintf(fname,"/tmp/namd.table.pe%d.dat",CkMyPe());
1308  FILE *f = fopen(fname,"w");
1309  for ( i=0; i<(n-1); ++i ) {
1310  const BigReal r2_base = r2_delta * ( 1 << (i/64) );
1311  const BigReal r2_del = r2_base / 64.0;
1312  const BigReal r2 = r2_base - r2_delta + r2_del * (i%64);
1313  BigReal *t;
1314  if ( r2 + r2_delta != r2_table[i] ) fprintf(f,"r2 error! ");
1315  fprintf(f,"%g",r2);
1316  t = fast_table + 4*i;
1317  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1318  t = scor_table + 4*i;
1319  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1320  t = slow_table + 4*i;
1321  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1322  t = corr_table + 4*i;
1323  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1324  t = full_table + 4*i;
1325  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1326  t = vdwa_table + 4*i;
1327  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1328  t = vdwb_table + 4*i;
1329  fprintf(f," %g %g %g %g", t[0], t[1], t[2], t[3]);
1330  fprintf(f,"\n");
1331  }
1332  fclose(f);
1333 #endif
1334 
1335  //Flip slow table to match table_four_i
1336  for ( i=0; i<n; ++i ) {
1337  BigReal tmp0, tmp1, tmp2, tmp3;
1338  tmp0 = slow_table [i*4 + 0];
1339  tmp1 = slow_table [i*4 + 1];
1340  tmp2 = slow_table [i*4 + 2];
1341  tmp3 = slow_table [i*4 + 3];
1342 
1343  slow_table [i*4 + 0] = tmp3;
1344  slow_table [i*4 + 1] = tmp2;
1345  slow_table [i*4 + 2] = tmp1;
1346  slow_table [i*4 + 3] = tmp0;
1347  }
1348 
1349  #ifdef NAMD_MIC
1350  send_build_mic_force_table();
1351  #endif
1352 }
1353 
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(* 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 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 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_slow_fullelect(nonbonded *)
static void calc_pair(nonbonded *)
static void calc_self_go(nonbonded *)
#define iout
Definition: InfoStream.h:51
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
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 *)
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_self_energy_merge_fullelect_fulldisp(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_self_energy_slow_fullelect_tabener(nonbonded *)
void NAMD_bug(const char *err_msg)
Definition: common.C:195
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_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 *)
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:147
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 *)
static void calc_self_merge_fullelect_fulldisp(nonbonded *)
int get_num_vdw_params(void)
Definition: Parameters.h:602
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 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_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(* calcFullPairEnergy)(nonbonded *)
static BigReal * corr_table
static BigReal * table_short
static void calc_pair_energy_merge_fullelect_fulldisp(nonbonded *)
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_pair_fullelect_tabener(nonbonded *)
static void calc_pair_energy_merge_fullelect_ti(nonbonded *)
std::ostream & iERROR(std::ostream &s)
Definition: InfoStream.C:83
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 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_pair_merge_fullelect_fulldisp(nonbonded *)
static void calc_self_merge_fullelect_pprof(nonbonded *)
static void calc_self_energy_slow_fullelect_go(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 *)