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