coulombLennardJones.cl 2.91 KB
Newer Older
1
#if USE_EWALD
2
3
bool needCorrection = isExcluded && atom1 != atom2 && atom1 < NUM_ATOMS && atom2 < NUM_ATOMS;
if (!isExcluded || needCorrection) {
4
    real tempForce = 0;
5
    if (r2 < CUTOFF_SQUARED || needCorrection) {
6
7
8
        const real alphaR = EWALD_ALPHA*r;
        const real expAlphaRSqr = EXP(-alphaR*alphaR);
        const real prefactor = 138.935456f*posq1.w*posq2.w*invR;
9

10
        // This approximation for erfc is from Abramowitz and Stegun (1964) p. 299.  They cite the following as
11
        // the original source: C. Hastings, Jr., Approximations for Digital Computers (1955).  It has a maximum
12
        // error of 3e-7.
13

14
        real t = 1.0f+(0.0705230784f+(0.0422820123f+(0.0092705272f+(0.0001520143f+(0.0002765672f+0.0000430638f*alphaR)*alphaR)*alphaR)*alphaR)*alphaR)*alphaR;
15
16
17
        t *= t;
        t *= t;
        t *= t;
18
        const real erfcAlphaR = RECIP(t*t);
19
20
        if (needCorrection) {
            // Subtract off the part of this interaction that was included in the reciprocal space contribution.
21

22
23
24
25
            tempForce = -prefactor*((1.0f-erfcAlphaR)-alphaR*expAlphaRSqr*TWO_OVER_SQRT_PI);
            tempEnergy += -prefactor*(1.0f-erfcAlphaR);
        }
        else {
26
#if HAS_LENNARD_JONES
27
28
            real sig = sigmaEpsilon1.x + sigmaEpsilon2.x;
            real sig2 = invR*sig;
29
            sig2 *= sig2;
30
31
            real sig6 = sig2*sig2*sig2;
            real epssig6 = sig6*(sigmaEpsilon1.y*sigmaEpsilon2.y);
32
33
            tempForce = epssig6*(12.0f*sig6 - 6.0f) + prefactor*(erfcAlphaR+alphaR*expAlphaRSqr*TWO_OVER_SQRT_PI);
            tempEnergy += epssig6*(sig6 - 1.0f) + prefactor*erfcAlphaR;
34
#else
35
36
            tempForce = prefactor*(erfcAlphaR+alphaR*expAlphaRSqr*TWO_OVER_SQRT_PI);
            tempEnergy += prefactor*erfcAlphaR;
37
#endif
38
        }
39
    }
40
    dEdR += tempForce*invR*invR;
41
42
}
#else
43
{
44
45
46
47
48
#ifdef USE_DOUBLE_PRECISION
    unsigned long includeInteraction;
#else
    unsigned int includeInteraction;
#endif
49
#ifdef USE_CUTOFF
50
    includeInteraction = (!isExcluded && r2 < CUTOFF_SQUARED);
51
#else
52
    includeInteraction = (!isExcluded);
53
#endif
54
    real tempForce = 0;
55
  #if HAS_LENNARD_JONES
56
57
    real sig = sigmaEpsilon1.x + sigmaEpsilon2.x;
    real sig2 = invR*sig;
58
    sig2 *= sig2;
59
60
    real sig6 = sig2*sig2*sig2;
    real epssig6 = sig6*(sigmaEpsilon1.y*sigmaEpsilon2.y);
61
    tempForce = epssig6*(12.0f*sig6 - 6.0f);
62
    tempEnergy += select((real) 0, epssig6*(sig6-1), includeInteraction);
63
64
65
  #endif
#if HAS_COULOMB
  #ifdef USE_CUTOFF
66
    const real prefactor = 138.935456f*posq1.w*posq2.w;
67
    tempForce += prefactor*(invR - 2.0f*REACTION_FIELD_K*r2);
68
    tempEnergy += select((real) 0, prefactor*(invR + REACTION_FIELD_K*r2 - REACTION_FIELD_C), includeInteraction);
69
  #else
70
    const real prefactor = 138.935456f*posq1.w*posq2.w*invR;
71
    tempForce += prefactor;
72
    tempEnergy += select((real) 0, prefactor, includeInteraction);
73
  #endif
74
#endif
75
    dEdR += select((real) 0, tempForce*invR*invR, includeInteraction);
76
}
77
#endif