Example #1
0
/* energy gradient (helper function) */
void addEgradt(double *dy, double *yt, double *rhot, int L, int R, int dim, int CSP, int CSD, double *scales2, double *scaleweight2, double energyweight)
{
    int CSPL = CSP*L;
    int CSDL = 1;

    int i, l, sl, si;

    if (dim == 2) {
#pragma omp parallel for schedule(static) shared(dy,yt,rhot,L,R,dim,CSP,CSD,CSPL,CSDL,scales2,scaleweight2,energyweight) private(i,l,sl,si)
    for (i=0; i<L; i++) { /* particle */
        double xi[2] = {rhot[INDRHOX(i,0)],rhot[INDRHOX(i,1)]};

        /* debug */
        /*mexPrintf("xi %f %f\n",xi[0],xi[1]);*/

        for (l=0; l<L; l++) { /* particle */
            double xl[2] = {rhot[INDRHOX(l,0)],rhot[INDRHOX(l,1)]};

            /* debug */
            /*mexPrintf("xl %f %f\n",xl[0],xl[1]);*/

            double ximxl[2]; VECMINUS(ximxl,xi,xl);
            double v = VECDOT2(ximxl,ximxl);

            for (sl=0; sl<R; sl++) { /* scale */
                double alsl[2] = {rhot[INDRHOP(l,0,sl)],rhot[INDRHOP(l,1,sl)]};
                double aisl[2] = {rhot[INDRHOP(i,0,sl)],rhot[INDRHOP(i,1,sl)]};
                double rsl2 = scales2[sl];
                double swsl2 = scaleweight2[sl];
                double kbasesl = exp(-v/rsl2);
                double ksl = Ks(kbasesl,swsl2);
                double d1ksl = D1Ks(kbasesl,rsl2,swsl2);
                double d1kslXximxl[2]; VECSCALAR(d1kslXximxl,d1ksl,ximxl);
                double d2ksl = D2Ks(kbasesl,rsl2,swsl2);

                double aislTXalsl; VECDOT(aislTXalsl,aisl,alsl);

                /* dx */
                double vt1[2]; VECSCALAR(vt1,energyweight*4*d1ksl*aislTXalsl,ximxl);
                dy[INDYX(i,0,0,0,0)] += vt1[0];
                dy[INDYX(i,1,0,0,0)] += vt1[1];

                /* da */
                VECSCALAR(vt1,energyweight*2*ksl,alsl);
                dy[INDYP(i,0,sl,0,0,0)] += vt1[0];
                dy[INDYP(i,1,sl,0,0,0)] += vt1[1];
            }
        }
    }
    } else {
#pragma omp parallel for schedule(static) shared(dy,yt,rhot,L,R,dim,CSP,CSD,CSPL,CSDL,scales2,scaleweight2,energyweight) private(i,l,sl,si)
    for (i=0; i<L; i++) { /* particle */
        double xi[3] = {rhot[INDRHOX(i,0)],rhot[INDRHOX(i,1)],rhot[INDRHOX(i,2)]};

        for (l=0; l<L; l++) { /* particle */
            double xl[3] = {rhot[INDRHOX(l,0)],rhot[INDRHOX(l,1)],rhot[INDRHOX(l,2)]};

            double ximxl[3]; _3VECMINUS(ximxl,xi,xl);
            double v = _3VECDOT2(ximxl,ximxl);

            for (sl=0; sl<R; sl++) { /* scale */
                double alsl[3] = {rhot[INDRHOP(l,0,sl)],rhot[INDRHOP(l,1,sl)],rhot[INDRHOP(l,2,sl)]};
                double aisl[3] = {rhot[INDRHOP(i,0,sl)],rhot[INDRHOP(i,1,sl)],rhot[INDRHOP(i,2,sl)]};
                double rsl2 = scales2[sl];
                double swsl2 = scaleweight2[sl];
                double kbasesl = exp(-v/rsl2);
                double ksl = Ks(kbasesl,swsl2);
                double d1ksl = D1Ks(kbasesl,rsl2,swsl2);
                double d1kslXximxl[3]; _3VECSCALAR(d1kslXximxl,d1ksl,ximxl);
                double d2ksl = D2Ks(kbasesl,rsl2,swsl2);

                double aislTXalsl; _3VECDOT(aislTXalsl,aisl,alsl);

                /* dx */
                double vt1[3]; _3VECSCALAR(vt1,energyweight*4*d1ksl*aislTXalsl,ximxl);
                dy[INDYX(i,0,0,0,0)] += vt1[0];
                dy[INDYX(i,1,0,0,0)] += vt1[1];
                dy[INDYX(i,2,0,0,0)] += vt1[2];

                /* da */
                _3VECSCALAR(vt1,energyweight*2*ksl,alsl);
                dy[INDYP(i,0,sl,0,0,0)] += vt1[0];
                dy[INDYP(i,1,sl,0,0,0)] += vt1[1];
                dy[INDYP(i,2,sl,0,0,0)] += vt1[2];
            }
        }
    }
    }
}
Example #2
0
int Fbonded_eval_impr_term(Fbonded *p,
    const ImprPrm *prm,
    const dvec *pos_i,
    const dvec *pos_j,
    const dvec *pos_k,
    const dvec *pos_l,
    dvec *f_i,
    dvec *f_j,
    dvec *f_k,
    dvec *f_l,
    dreal *u,
    dreal virial[NELEMS_VIRIAL]) {
  dvec r12, r23, r34;
  dvec A, B, C;
  dreal rA, rB, rC;
  dreal cos_phi, sin_phi, phi;
  dreal K, K1;
  dvec f1, f2, f3;

  dreal k = prm->k_impr;
  dreal delta = prm->psi0;
  dreal diff;

  Domain_shortest_vec(p->domain, &r12, pos_i, pos_j);
  Domain_shortest_vec(p->domain, &r23, pos_j, pos_k);
  Domain_shortest_vec(p->domain, &r34, pos_k, pos_l);

  VECCROSS(A, r12, r23);
  VECCROSS(B, r23, r34);
  VECCROSS(C, r23, A);

  rA = 1 / sqrt(VECLEN2(A));
  rB = 1 / sqrt(VECLEN2(B));
  rC = 1 / sqrt(VECLEN2(C));

  VECMUL(B, rB, B);  /* normalize B */
  cos_phi = VECDOT(A, B) * rA;
  sin_phi = VECDOT(C, B) * rC;

  phi = -atan2(sin_phi, cos_phi);

  diff = phi - delta;
  if      (diff < -M_PI)  diff += 2.0 * M_PI;
  else if (diff >  M_PI)  diff -= 2.0 * M_PI;
  K = k * diff * diff;
  K1 = 2.0 * k * diff;

  if (fabs(sin_phi) > 0.1) {
    dvec dcosdA, dcosdB;
    dvec tv1, tv2;

    /* use sine version to avoid 1/cos terms */

    VECMUL(A, rA, A);  /* normalize A */
    VECMSUB(dcosdA, cos_phi, A, B);
    VECMUL(dcosdA, rA, dcosdA);
    VECMSUB(dcosdB, cos_phi, B, A);
    VECMUL(dcosdB, rB, dcosdB);

    K1 /= sin_phi;
    VECCROSS(f1, r23, dcosdA);
    VECMUL(f1, K1, f1);
    VECCROSS(f3, dcosdB, r23);
    VECMUL(f3, K1, f3);

    VECCROSS(tv1, dcosdA, r12);
    VECCROSS(tv2, r34, dcosdB);
    VECADD(f2, tv1, tv2);
    VECMUL(f2, K1, f2);
  }
  else {
    dvec dsindB, dsindC;

    /* phi is too close to 0 or pi, use cos version to avoid 1/sin */

    VECMUL(C, rC, C);  /* normalize C */
    VECMSUB(dsindC, sin_phi, C, B);
    VECMUL(dsindC, rC, dsindC);
    VECMSUB(dsindB, sin_phi, B, C);
    VECMUL(dsindB, rB, dsindB);

    K1 /= -cos_phi;
    f1.x = K1 * ((r23.y * r23.y + r23.z * r23.z) * dsindC.x
                 - r23.x * r23.y * dsindC.y
                 - r23.x * r23.z * dsindC.z);
    f1.y = K1 * ((r23.z * r23.z + r23.x * r23.x) * dsindC.y
                 - r23.y * r23.z * dsindC.z
                 - r23.y * r23.x * dsindC.x);
    f1.z = K1 * ((r23.x * r23.x + r23.y * r23.y) * dsindC.z
                 - r23.z * r23.x * dsindC.x
                 - r23.z * r23.y * dsindC.y);

    VECCROSS(f3, dsindB, r23);
    VECMUL(f3, K1, f3);

    f2.x = K1 * (-(r23.y * r12.y + r23.z * r12.z) * dsindC.x
                 + (2.0 * r23.x * r12.y - r12.x * r23.y) * dsindC.y
                 + (2.0 * r23.x * r12.z - r12.x * r23.z) * dsindC.z
                 + dsindB.z * r34.y - dsindB.y * r34.z);
    f2.y = K1 * (-(r23.z * r12.z + r23.x * r12.x) * dsindC.y
                 + (2.0 * r23.y * r12.z - r12.y * r23.z) * dsindC.z
                 + (2.0 * r23.y * r12.x - r12.y * r23.x) * dsindC.x
                 + dsindB.x * r34.z - dsindB.z * r34.x);
    f2.z = K1 * (-(r23.x * r12.x + r23.y * r12.y) * dsindC.z
                 + (2.0 * r23.z * r12.x - r12.z * r23.x) * dsindC.x
                 + (2.0 * r23.z * r12.y - r12.z * r23.y) * dsindC.y
                 + dsindB.y * r34.x - dsindB.x * r34.y);
  }
  *u += K;
  VECADD(*f_i, *f_i, f1);
  f_j->x += f2.x - f1.x;
  f_j->y += f2.y - f1.y;
  f_j->z += f2.z - f1.z;
  f_k->x += f3.x - f2.x;
  f_k->y += f3.y - f2.y;
  f_k->z += f3.z - f2.z;
  VECSUB(*f_l, *f_l, f3);
  virial[VIRIAL_XX] += (f1.x * r12.x + f2.x * r23.x + f3.x * r34.x);
  virial[VIRIAL_XY] += (f1.x * r12.y + f2.x * r23.y + f3.x * r34.y);
  virial[VIRIAL_XZ] += (f1.x * r12.z + f2.x * r23.z + f3.x * r34.z);
  virial[VIRIAL_YY] += (f1.y * r12.y + f2.y * r23.y + f3.y * r34.y);
  virial[VIRIAL_YZ] += (f1.y * r12.z + f2.y * r23.z + f3.y * r34.z);
  virial[VIRIAL_ZZ] += (f1.z * r12.z + f2.z * r23.z + f3.z * r34.z);
  return OK;
}
Example #3
0
/* The computational routine */
void gradOrder1ScaleC(double *dy, double *yt, double *rhot, int L, int R, int dim, int CSP, int CSD, double *scales2, double *scaleweight2, double energyweight)
{
    /* dy already initialized to zeros */
    int CSPL = CSP*L;
    int CSDL = 1;
    double invR = 1.0/R;

    int i, l, sl, si;

    if (dim == 2) {
#pragma omp parallel for schedule(static) shared(dy,yt,rhot,L,R,dim,CSP,CSD,CSPL,CSDL,scales2,scaleweight2) private(i,l,sl,si)
    for (i=0; i<L; i++) { /* particle */
        double xi[2] = {rhot[INDRHOX(i,0)],rhot[INDRHOX(i,1)]};
        double dxi[2] = {yt[INDYX(i,0,0,0,0)],yt[INDYX(i,1,0,0,0)]};

        for (l=0; l<L; l++) { /* particle */
            double xl[2] = {rhot[INDRHOX(l,0)],rhot[INDRHOX(l,1)]};
            double dxl[2] = {yt[INDYX(l,0,0,0,0)],yt[INDYX(l,1,0,0,0)]};

            double ximxl[2]; VECMINUS(ximxl,xi,xl);
            double v = VECDOT2(ximxl,ximxl);

            for (sl=0; sl<R; sl++) { /* scale */
                double alsl[2] = {rhot[INDRHOP(l,0,sl)],rhot[INDRHOP(l,1,sl)]};
                double aisl[2] = {rhot[INDRHOP(i,0,sl)],rhot[INDRHOP(i,1,sl)]};
                double rsl2 = scales2[sl];
                double swsl2 = scaleweight2[sl];
                double kbasesl = exp(-v/rsl2);
                double d1ksl = D1Ks(kbasesl,rsl2,swsl2);
                double d1kslXximxl[2]; VECSCALAR(d1kslXximxl,d1ksl,ximxl);

                double dalsl[2] = {yt[INDYP(l,0,sl,0,0,0)],yt[INDYP(l,1,sl,0,0,0)]};

                /* dx */
                double rt1; VECDOT(rt1,aisl,dxl);
                double rt2; VECDOT(rt2,alsl,dxi);
                double vt1[2]; VECSCALAR(vt1,2*(rt1+rt2),d1kslXximxl);
                dy[INDYX(i,0,0,0,0)] += vt1[0];
                dy[INDYX(i,1,0,0,0)] += vt1[1];

                for (si=0; si<R; si++) { /* scale */
                    double alsi[2] = {rhot[INDRHOP(l,0,si)],rhot[INDRHOP(l,1,si)]};
                    double aisi[2] = {rhot[INDRHOP(i,0,si)],rhot[INDRHOP(i,1,si)]};
                    double daisi[2] = {yt[INDYP(i,0,si,0,0,0)],yt[INDYP(i,1,si,0,0,0)]};
                    double daisl[2] = {yt[INDYP(i,0,sl,0,0,0)],yt[INDYP(i,1,sl,0,0,0)]};

                    double rsi2 = scales2[si];
                    double swsi2 = scaleweight2[si];
                    double kbasesi = exp(-v/rsi2);
                    double ksi = Ks(kbasesi,swsi2);
                    double d1ksi = D1Ks(kbasesi,rsi2,swsi2);
                    double d2ksi = D2Ks(kbasesi,rsi2,swsi2);

                    double aislTXalsi; VECDOT(aislTXalsi,aisl,alsi);
                    double aisiTXalsl; VECDOT(aisiTXalsl,aisi,alsl);

                    /* dx */
                    VECSCALAR(vt1,aislTXalsi,daisl);
                    double vt2[2]; VECSCALAR(vt2,aisiTXalsl,dalsl);
                    double vt3[2]; VECMINUS(vt3,vt1,vt2);
                    double rt; VECDOT(rt,ximxl,vt3);
                    VECSCALAR(vt1,-2*d1ksi,vt3);
                    VECSCALAR(vt2,-4*d2ksi*rt,ximxl);
                    VECADD(vt3,vt1,vt2);
                    dy[INDYX(i,0,0,0,0)] += vt3[0];
                    dy[INDYX(i,1,0,0,0)] += vt3[1];

                    /* da */
                    VECSCALAR(vt1,d1ksl,daisi);
                    VECSCALAR(vt2,d1ksi,dalsl);
                    VECMINUS(vt3,vt1,vt2);
                    VECDOT(rt,ximxl,vt3);
                    VECSCALAR(vt1,-2*rt,alsl);
                    VECSCALAR(vt2,invR*ksi,dxl);
                    VECADD(vt3,vt1,vt2);

                    dy[INDYP(i,0,si,0,0,0)] += vt3[0];
                    dy[INDYP(i,1,si,0,0,0)] += vt3[1];
                }
            }
        }
    }
    } else {
/* #pragma omp parallel for schedule(static) shared(dy,yt,rhot,L,R,dim,CSP,CSD,CSPL,CSDL,scales2,scaleweight2) private(i,l,sl,si)*/
    for (i=0; i<L; i++) { /* particle */
        double xi[3] = {rhot[INDRHOX(i,0)],rhot[INDRHOX(i,1)],rhot[INDRHOX(i,2)]};
        double dxi[3] = {yt[INDYX(i,0,0,0,0)],yt[INDYX(i,1,0,0,0)],yt[INDYX(i,2,0,0,0)]};

        for (l=0; l<L; l++) { /* particle */
            double xl[3] = {rhot[INDRHOX(l,0)],rhot[INDRHOX(l,1)],rhot[INDRHOX(l,2)]};
            double dxl[3] = {yt[INDYX(l,0,0,0,0)],yt[INDYX(l,1,0,0,0)],yt[INDYX(l,2,0,0,0)]};

            double ximxl[3]; _3VECMINUS(ximxl,xi,xl);
            double v = _3VECDOT2(ximxl,ximxl);

            for (sl=0; sl<R; sl++) { /* scale */
                double alsl[3] = {rhot[INDRHOP(l,0,sl)],rhot[INDRHOP(l,1,sl)],rhot[INDRHOP(l,2,sl)]};
                double aisl[3] = {rhot[INDRHOP(i,0,sl)],rhot[INDRHOP(i,1,sl)],rhot[INDRHOP(i,2,sl)]};
                double rsl2 = scales2[sl];
                double swsl2 = scaleweight2[sl];
                double kbasesl = exp(-v/rsl2);
                double d1ksl = D1Ks(kbasesl,rsl2,swsl2);
                double d1kslXximxl[3]; _3VECSCALAR(d1kslXximxl,d1ksl,ximxl);

                double dalsl[3] = {yt[INDYP(l,0,sl,0,0,0)],yt[INDYP(l,1,sl,0,0,0)],yt[INDYP(l,2,sl,0,0,0)]};

                /* dx */
                double rt1; _3VECDOT(rt1,aisl,dxl);
                double rt2; _3VECDOT(rt2,alsl,dxi);
                double vt1[3]; _3VECSCALAR(vt1,2*(rt1+rt2),d1kslXximxl);
                dy[INDYX(i,0,0,0,0)] += vt1[0];
                dy[INDYX(i,1,0,0,0)] += vt1[1];
                dy[INDYX(i,2,0,0,0)] += vt1[2];

                for (si=0; si<R; si++) { /* scale */
                    double alsi[3] = {rhot[INDRHOP(l,0,si)],rhot[INDRHOP(l,1,si)],rhot[INDRHOP(l,2,si)]};
                    double aisi[3] = {rhot[INDRHOP(i,0,si)],rhot[INDRHOP(i,1,si)],rhot[INDRHOP(i,2,si)]};
                    double daisi[3] = {yt[INDYP(i,0,si,0,0,0)],yt[INDYP(i,1,si,0,0,0)],yt[INDYP(i,2,si,0,0,0)]};
                    double daisl[3] = {yt[INDYP(i,0,sl,0,0,0)],yt[INDYP(i,1,sl,0,0,0)],yt[INDYP(i,2,sl,0,0,0)]};

                    double rsi2 = scales2[si];
                    double swsi2 = scaleweight2[si];
                    double kbasesi = exp(-v/rsi2);
                    double ksi = Ks(kbasesi,swsi2);
                    double d1ksi = D1Ks(kbasesi,rsi2,swsi2);
                    double d2ksi = D2Ks(kbasesi,rsi2,swsi2);

                    double aislTXalsi; _3VECDOT(aislTXalsi,aisl,alsi);
                    double aisiTXalsl; _3VECDOT(aisiTXalsl,aisi,alsl);

                    /* dx */
                    _3VECSCALAR(vt1,aislTXalsi,daisl);
                    double vt2[3]; _3VECSCALAR(vt2,aisiTXalsl,dalsl);
                    double vt3[3]; _3VECMINUS(vt3,vt1,vt2);
                    double rt; _3VECDOT(rt,ximxl,vt3);
                    _3VECSCALAR(vt1,-2*d1ksi,vt3);
                    _3VECSCALAR(vt2,-4*d2ksi*rt,ximxl);
                    _3VECADD(vt3,vt1,vt2);
                    dy[INDYX(i,0,0,0,0)] += vt3[0];
                    dy[INDYX(i,1,0,0,0)] += vt3[1];
                    dy[INDYX(i,2,0,0,0)] += vt3[2];

                    /* da */
                    _3VECSCALAR(vt1,d1ksl,daisi);
                    _3VECSCALAR(vt2,d1ksi,dalsl);
                    _3VECMINUS(vt3,vt1,vt2);
                    _3VECDOT(rt,ximxl,vt3);
                    _3VECSCALAR(vt1,-2*rt,alsl);
                    _3VECSCALAR(vt2,invR*ksi,dxl);
                    _3VECADD(vt3,vt1,vt2);

                    dy[INDYP(i,0,si,0,0,0)] += vt3[0];
                    dy[INDYP(i,1,si,0,0,0)] += vt3[1];
                    dy[INDYP(i,2,si,0,0,0)] += vt3[2];
                }
            }
        }
    }
    }

    addEgradt(dy,yt,rhot,L,R,dim,CSP,CSD,scales2,scaleweight2,energyweight);
}
Example #4
0
/* The computational routine */
double energyScaleC(double *Et, double *rhot, int L, int R, int dim, int CSP, double *scales2, double *scaleweight2)
{
    /* Et already initialized to zeros */
    int CSPL = CSP*L;

    int i, l, sl;
    double Ett = 0;

    if (dim == 2) {
#pragma omp parallel for schedule(static) shared(rhot,L,R,dim,CSP,CSPL,scales2,scaleweight2) private(i,l,sl) reduction(+:Ett)
    for (i=0; i<L; i++) { /* particle */
        double xi[2] = {rhot[INDRHOX(i,0)],rhot[INDRHOX(i,1)]};

        for (l=0; l<L; l++) { /* particle */
            double xl[2] = {rhot[INDRHOX(l,0)],rhot[INDRHOX(l,1)]};

            double ximxl[2]; VECMINUS(ximxl,xi,xl);
            double v = VECDOT2(ximxl,ximxl);

            for (sl=0; sl<R; sl++) { /* scale */
                double alsl[2] = {rhot[INDRHOP(l,0,sl)],rhot[INDRHOP(l,1,sl)]};
                double aisl[2] = {rhot[INDRHOP(i,0,sl)],rhot[INDRHOP(i,1,sl)]};
                double rsl2 = scales2[sl];
                double swsl2 = scaleweight2[sl];
                double kbasesl = exp(-v/rsl2);
                double ksl = Ks(kbasesl,swsl2);

                double aislTXalsi; VECDOT(aislTXalsi,aisl,alsl);

                Ett = Ett+ksl*aislTXalsi;
            }
        }
    }
    } else {
#pragma omp parallel for schedule(static) shared(rhot,L,R,dim,CSP,CSPL,scales2,scaleweight2) private(i,l,sl) reduction(+:Ett)
    for (i=0; i<L; i++) { /* particle */
        double xi[3] = {rhot[INDRHOX(i,0)],rhot[INDRHOX(i,1)],rhot[INDRHOX(i,2)]};

        for (l=0; l<L; l++) { /* particle */
            double xl[3] = {rhot[INDRHOX(l,0)],rhot[INDRHOX(l,1)],rhot[INDRHOX(l,2)]};

            double ximxl[3]; _3VECMINUS(ximxl,xi,xl);
            double v = _3VECDOT2(ximxl,ximxl);

            for (sl=0; sl<R; sl++) { /* scale */
                double alsl[3] = {rhot[INDRHOP(l,0,sl)],rhot[INDRHOP(l,1,sl)],rhot[INDRHOP(l,2,sl)]};
                double aisl[3] = {rhot[INDRHOP(i,0,sl)],rhot[INDRHOP(i,1,sl)],rhot[INDRHOP(i,2,sl)]};
                double rsl2 = scales2[sl];
                double swsl2 = scaleweight2[sl];
                double kbasesl = exp(-v/rsl2);
                double ksl = Ks(kbasesl,swsl2);

                double aislTXalsi; _3VECDOT(aislTXalsi,aisl,alsl);

                Ett = Ett+ksl*aislTXalsi;
            }
        }
    }
    }

    Et[0] = Ett;
}