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