示例#1
0
static void do_lincsp(rvec *x,rvec *f,rvec *fp,t_pbc *pbc,
                      struct gmx_lincsdata *lincsd,real *invmass,
                      int econq,real *dvdlambda,
                      gmx_bool bCalcVir,tensor rmdf)
{
    int     b,i,j,k,n;
    real    tmp0,tmp1,tmp2,im1,im2,mvb,rlen,len,wfac,lam;  
    rvec    dx;
    int     ncons,*bla,*blnr,*blbnb;
    rvec    *r;
    real    *blc,*blmf,*blcc,*rhs1,*rhs2,*sol;
    
    ncons  = lincsd->nc;
    bla    = lincsd->bla;
    r      = lincsd->tmpv;
    blnr   = lincsd->blnr;
    blbnb  = lincsd->blbnb;
    if (econq != econqForce)
    {
        /* Use mass-weighted parameters */
        blc  = lincsd->blc;
        blmf = lincsd->blmf; 
    }
    else
    {
        /* Use non mass-weighted parameters */
        blc  = lincsd->blc1;
        blmf = lincsd->blmf1;
    }
    blcc   = lincsd->tmpncc;
    rhs1   = lincsd->tmp1;
    rhs2   = lincsd->tmp2;
    sol    = lincsd->tmp3;
    
    if (econq != econqForce)
    {
        dvdlambda = NULL;
    }
    
    /* Compute normalized i-j vectors */
    if (pbc)
    {
        for(b=0; b<ncons; b++)
        {
            pbc_dx_aiuc(pbc,x[bla[2*b]],x[bla[2*b+1]],dx);
            unitv(dx,r[b]);
        }
    }
    else
    {
        for(b=0; b<ncons; b++)
        {
            rvec_sub(x[bla[2*b]],x[bla[2*b+1]],dx);
            unitv(dx,r[b]);
        } /* 16 ncons flops */
    }
    
    for(b=0; b<ncons; b++)
    {
        tmp0 = r[b][0];
        tmp1 = r[b][1];
        tmp2 = r[b][2];
        i = bla[2*b];
        j = bla[2*b+1];
        for(n=blnr[b]; n<blnr[b+1]; n++)
        {
            k = blbnb[n];
            blcc[n] = blmf[n]*(tmp0*r[k][0] + tmp1*r[k][1] + tmp2*r[k][2]); 
        } /* 6 nr flops */
        mvb = blc[b]*(tmp0*(f[i][0] - f[j][0]) +
                      tmp1*(f[i][1] - f[j][1]) +    
                      tmp2*(f[i][2] - f[j][2]));
        rhs1[b] = mvb;
        sol[b]  = mvb;
        /* 7 flops */
    }
    /* Together: 23*ncons + 6*nrtot flops */
    
    lincs_matrix_expand(lincsd,blcc,rhs1,rhs2,sol);
    /* nrec*(ncons+2*nrtot) flops */
    
    if (econq != econqForce)
    {
        for(b=0; b<ncons; b++)
        {
            /* With econqDeriv_FlexCon only use the flexible constraints */
            if (econq != econqDeriv_FlexCon ||
                (lincsd->bllen0[b] == 0 && lincsd->ddist[b] == 0))
            {
                i = bla[2*b];
                j = bla[2*b+1];
                mvb = blc[b]*sol[b];
                im1 = invmass[i];
                im2 = invmass[j];
                tmp0 = r[b][0]*mvb;
                tmp1 = r[b][1]*mvb;
                tmp2 = r[b][2]*mvb;
                fp[i][0] -= tmp0*im1;
                fp[i][1] -= tmp1*im1;
                fp[i][2] -= tmp2*im1;
                fp[j][0] += tmp0*im2;
                fp[j][1] += tmp1*im2;
                fp[j][2] += tmp2*im2;
                if (dvdlambda)
                {
                    /* This is only correct with forces and invmass=1 */
                    *dvdlambda -= mvb*lincsd->ddist[b];
                }
            }
        } /* 16 ncons flops */
    }
    else
    {
        for(b=0; b<ncons; b++)
        {
            i = bla[2*b];
            j = bla[2*b+1];
            mvb = blc[b]*sol[b];
            tmp0 = r[b][0]*mvb;
            tmp1 = r[b][1]*mvb;
            tmp2 = r[b][2]*mvb;
            fp[i][0] -= tmp0;
            fp[i][1] -= tmp1;
            fp[i][2] -= tmp2;
            fp[j][0] += tmp0;
            fp[j][1] += tmp1;
            fp[j][2] += tmp2;
            if (dvdlambda)
            {
                *dvdlambda -= mvb*lincsd->ddist[b];
            }
        }
        /* 10 ncons flops */
    }
    
    if (bCalcVir)
    {
        /* Constraint virial,
         * determines sum r_bond x delta f,
         * where delta f is the constraint correction
         * of the quantity that is being constrained.
         */
        for(b=0; b<ncons; b++)
        {
            mvb = lincsd->bllen[b]*blc[b]*sol[b];
            for(i=0; i<DIM; i++)
            {
                tmp1 = mvb*r[b][i];
                for(j=0; j<DIM; j++)
                {
                    rmdf[i][j] += tmp1*r[b][j];
                }
            }
        } /* 23 ncons flops */
    }
}
示例#2
0
static void do_lincs(rvec *x,rvec *xp,matrix box,t_pbc *pbc,
                     struct gmx_lincsdata *lincsd,real *invmass,
					 t_commrec *cr,
                     real wangle,int *warn,
                     real invdt,rvec *v,
                     gmx_bool bCalcVir,tensor rmdr)
{
    int     b,i,j,k,n,iter;
    real    tmp0,tmp1,tmp2,im1,im2,mvb,rlen,len,len2,dlen2,wfac,lam;  
    rvec    dx;
    int     ncons,*bla,*blnr,*blbnb;
    rvec    *r;
    real    *blc,*blmf,*bllen,*blcc,*rhs1,*rhs2,*sol,*lambda;
    int     *nlocat;
    
    ncons  = lincsd->nc;
    bla    = lincsd->bla;
    r      = lincsd->tmpv;
    blnr   = lincsd->blnr;
    blbnb  = lincsd->blbnb;
    blc    = lincsd->blc;
    blmf   = lincsd->blmf;
    bllen  = lincsd->bllen;
    blcc   = lincsd->tmpncc;
    rhs1   = lincsd->tmp1;
    rhs2   = lincsd->tmp2;
    sol    = lincsd->tmp3;
    lambda = lincsd->lambda;
    
    if (DOMAINDECOMP(cr) && cr->dd->constraints)
    {
        nlocat = dd_constraints_nlocalatoms(cr->dd);
    }
    else if (PARTDECOMP(cr))
    {
        nlocat = pd_constraints_nlocalatoms(cr->pd);
    }
    else
    {
        nlocat = NULL;
    }
    
    *warn = 0;

    if (pbc)
    {
        /* Compute normalized i-j vectors */
        for(b=0; b<ncons; b++)
        {
            pbc_dx_aiuc(pbc,x[bla[2*b]],x[bla[2*b+1]],dx);
            unitv(dx,r[b]);
        }  
        for(b=0; b<ncons; b++)
        {
            for(n=blnr[b]; n<blnr[b+1]; n++)
            {
                blcc[n] = blmf[n]*iprod(r[b],r[blbnb[n]]);
            }
            pbc_dx_aiuc(pbc,xp[bla[2*b]],xp[bla[2*b+1]],dx);
            mvb = blc[b]*(iprod(r[b],dx) - bllen[b]);
            rhs1[b] = mvb;
            sol[b]  = mvb;
        }
    }
    else
    {
        /* Compute normalized i-j vectors */
        for(b=0; b<ncons; b++)
        {
            i = bla[2*b];
            j = bla[2*b+1];
            tmp0 = x[i][0] - x[j][0];
            tmp1 = x[i][1] - x[j][1];
            tmp2 = x[i][2] - x[j][2];
            rlen = gmx_invsqrt(tmp0*tmp0+tmp1*tmp1+tmp2*tmp2);
            r[b][0] = rlen*tmp0;
            r[b][1] = rlen*tmp1;
            r[b][2] = rlen*tmp2;
        } /* 16 ncons flops */
        
        for(b=0; b<ncons; b++)
        {
            tmp0 = r[b][0];
            tmp1 = r[b][1];
            tmp2 = r[b][2];
            len = bllen[b];
            i = bla[2*b];
            j = bla[2*b+1];
            for(n=blnr[b]; n<blnr[b+1]; n++)
            {
                k = blbnb[n];
                blcc[n] = blmf[n]*(tmp0*r[k][0] + tmp1*r[k][1] + tmp2*r[k][2]); 
            } /* 6 nr flops */
            mvb = blc[b]*(tmp0*(xp[i][0] - xp[j][0]) +
                          tmp1*(xp[i][1] - xp[j][1]) +    
                          tmp2*(xp[i][2] - xp[j][2]) - len);
            rhs1[b] = mvb;
            sol[b]  = mvb;
            /* 10 flops */
        }
        /* Together: 26*ncons + 6*nrtot flops */
    }
    
    lincs_matrix_expand(lincsd,blcc,rhs1,rhs2,sol);
    /* nrec*(ncons+2*nrtot) flops */
    
    for(b=0; b<ncons; b++)
    {
        i = bla[2*b];
        j = bla[2*b+1];
        mvb = blc[b]*sol[b];
        lambda[b] = -mvb;
        im1 = invmass[i];
        im2 = invmass[j];
        tmp0 = r[b][0]*mvb;
        tmp1 = r[b][1]*mvb;
        tmp2 = r[b][2]*mvb;
        xp[i][0] -= tmp0*im1;
        xp[i][1] -= tmp1*im1;
        xp[i][2] -= tmp2*im1;
        xp[j][0] += tmp0*im2;
        xp[j][1] += tmp1*im2;
        xp[j][2] += tmp2*im2;
    } /* 16 ncons flops */


    /*     
     ********  Correction for centripetal effects  ********  
     */
  
    wfac = cos(DEG2RAD*wangle);
    wfac = wfac*wfac;
	
    for(iter=0; iter<lincsd->nIter; iter++)
    {
        if (DOMAINDECOMP(cr) && cr->dd->constraints)
        {
            /* Communicate the corrected non-local coordinates */
            dd_move_x_constraints(cr->dd,box,xp,NULL);
        } 
		else if (PARTDECOMP(cr))
		{
			pd_move_x_constraints(cr,xp,NULL);
		}	
        
        for(b=0; b<ncons; b++)
        {
            len = bllen[b];
            if (pbc)
            {
                pbc_dx_aiuc(pbc,xp[bla[2*b]],xp[bla[2*b+1]],dx);
            }
            else
            {
                rvec_sub(xp[bla[2*b]],xp[bla[2*b+1]],dx);
            }
            len2 = len*len;
            dlen2 = 2*len2 - norm2(dx);
            if (dlen2 < wfac*len2 && (nlocat==NULL || nlocat[b]))
            {
                *warn = b;
            }
            if (dlen2 > 0)
            {
                mvb = blc[b]*(len - dlen2*gmx_invsqrt(dlen2));
            }
            else
            {
                mvb = blc[b]*len;
            }
            rhs1[b] = mvb;
            sol[b]  = mvb;
        } /* 20*ncons flops */
        
        lincs_matrix_expand(lincsd,blcc,rhs1,rhs2,sol);
        /* nrec*(ncons+2*nrtot) flops */
        
        for(b=0; b<ncons; b++)
        {
            i = bla[2*b];
            j = bla[2*b+1];
            lam = lambda[b];
            mvb = blc[b]*sol[b];
            lambda[b] = lam - mvb;
            im1 = invmass[i];
            im2 = invmass[j];
            tmp0 = r[b][0]*mvb;
            tmp1 = r[b][1]*mvb;
            tmp2 = r[b][2]*mvb;
            xp[i][0] -= tmp0*im1;
            xp[i][1] -= tmp1*im1;
            xp[i][2] -= tmp2*im1;
            xp[j][0] += tmp0*im2;
            xp[j][1] += tmp1*im2;
            xp[j][2] += tmp2*im2;
        } /* 17 ncons flops */
    } /* nit*ncons*(37+9*nrec) flops */
    
    if (v)
    {
        /* Correct the velocities */
        for(b=0; b<ncons; b++)
        {
            i = bla[2*b];
            j = bla[2*b+1];
            im1 = invmass[i]*lambda[b]*invdt;
            im2 = invmass[j]*lambda[b]*invdt;
            v[i][0] += im1*r[b][0];
            v[i][1] += im1*r[b][1];
            v[i][2] += im1*r[b][2];
            v[j][0] -= im2*r[b][0];
            v[j][1] -= im2*r[b][1];
            v[j][2] -= im2*r[b][2];
        } /* 16 ncons flops */
    }
    
    if (nlocat)
    {
        /* Only account for local atoms */
        for(b=0; b<ncons; b++)
        {
            lambda[b] *= 0.5*nlocat[b];
        }
    }
    
    if (bCalcVir)
    {
        /* Constraint virial */
        for(b=0; b<ncons; b++)
        {
            tmp0 = bllen[b]*lambda[b];
            for(i=0; i<DIM; i++)
            {
                tmp1 = tmp0*r[b][i];
                for(j=0; j<DIM; j++)
                {
                    rmdr[i][j] -= tmp1*r[b][j];
                }
            }
        } /* 22 ncons flops */
    }
    
    /* Total:
     * 26*ncons + 6*nrtot + nrec*(ncons+2*nrtot)
     * + nit * (20*ncons + nrec*(ncons+2*nrtot) + 17 ncons)
     *
     * (26+nrec)*ncons + (6+2*nrec)*nrtot
     * + nit * ((37+nrec)*ncons + 2*nrec*nrtot)
     * if nit=1
     * (63+nrec)*ncons + (6+4*nrec)*nrtot
     */
}
示例#3
0
/* LINCS projection, works on derivatives of the coordinates */
static void do_lincsp(rvec *x,rvec *f,rvec *fp,t_pbc *pbc,
                      struct gmx_lincsdata *lincsd,int th,
                      real *invmass,
                      int econq,real *dvdlambda,
                      gmx_bool bCalcVir,tensor rmdf)
{
    int     b0,b1,b,i,j,k,n;
    real    tmp0,tmp1,tmp2,im1,im2,mvb,rlen,len,wfac,lam;  
    rvec    dx;
    int     *bla,*blnr,*blbnb;
    rvec    *r;
    real    *blc,*blmf,*blcc,*rhs1,*rhs2,*sol;

    b0 = lincsd->th[th].b0;
    b1 = lincsd->th[th].b1;
    
    bla    = lincsd->bla;
    r      = lincsd->tmpv;
    blnr   = lincsd->blnr;
    blbnb  = lincsd->blbnb;
    if (econq != econqForce)
    {
        /* Use mass-weighted parameters */
        blc  = lincsd->blc;
        blmf = lincsd->blmf; 
    }
    else
    {
        /* Use non mass-weighted parameters */
        blc  = lincsd->blc1;
        blmf = lincsd->blmf1;
    }
    blcc   = lincsd->tmpncc;
    rhs1   = lincsd->tmp1;
    rhs2   = lincsd->tmp2;
    sol    = lincsd->tmp3;
    
    /* Compute normalized i-j vectors */
    if (pbc)
    {
        for(b=b0; b<b1; b++)
        {
            pbc_dx_aiuc(pbc,x[bla[2*b]],x[bla[2*b+1]],dx);
            unitv(dx,r[b]);
        }
    }
    else
    {
        for(b=b0; b<b1; b++)
        {
            rvec_sub(x[bla[2*b]],x[bla[2*b+1]],dx);
            unitv(dx,r[b]);
        } /* 16 ncons flops */
    }
    
#pragma omp barrier
    for(b=b0; b<b1; b++)
    {
        tmp0 = r[b][0];
        tmp1 = r[b][1];
        tmp2 = r[b][2];
        i = bla[2*b];
        j = bla[2*b+1];
        for(n=blnr[b]; n<blnr[b+1]; n++)
        {
            k = blbnb[n];
            blcc[n] = blmf[n]*(tmp0*r[k][0] + tmp1*r[k][1] + tmp2*r[k][2]); 
        } /* 6 nr flops */
        mvb = blc[b]*(tmp0*(f[i][0] - f[j][0]) +
                      tmp1*(f[i][1] - f[j][1]) +    
                      tmp2*(f[i][2] - f[j][2]));
        rhs1[b] = mvb;
        sol[b]  = mvb;
        /* 7 flops */
    }
    /* Together: 23*ncons + 6*nrtot flops */
    
    lincs_matrix_expand(lincsd,b0,b1,blcc,rhs1,rhs2,sol);
    /* nrec*(ncons+2*nrtot) flops */
    
    if (econq == econqDeriv_FlexCon)
    {
        /* We only want to constraint the flexible constraints,
         * so we mask out the normal ones by setting sol to 0.
         */
        for(b=b0; b<b1; b++)
        {
            if (!(lincsd->bllen0[b] == 0 && lincsd->ddist[b] == 0))
            {
                sol[b] = 0;
            }
        }
    }

    if (econq != econqForce)
    {
        lincs_update_atoms(lincsd,th,1.0,sol,r,invmass,fp);
    }
    else
    {
        for(b=b0; b<b1; b++)
        {
            i = bla[2*b];
            j = bla[2*b+1];
            mvb = blc[b]*sol[b];
            tmp0 = r[b][0]*mvb;
            tmp1 = r[b][1]*mvb;
            tmp2 = r[b][2]*mvb;
            fp[i][0] -= tmp0;
            fp[i][1] -= tmp1;
            fp[i][2] -= tmp2;
            fp[j][0] += tmp0;
            fp[j][1] += tmp1;
            fp[j][2] += tmp2;
        }

        if (dvdlambda != NULL)
        {
#pragma omp barrier
            for(b=b0; b<b1; b++)
            {
                *dvdlambda -= blc[b]*sol[b]*lincsd->ddist[b];
            }
        }
        /* 10 ncons flops */
    }

    if (bCalcVir)
    {
        /* Constraint virial,
         * determines sum r_bond x delta f,
         * where delta f is the constraint correction
         * of the quantity that is being constrained.
         */
        for(b=b0; b<b1; b++)
        {
            mvb = lincsd->bllen[b]*blc[b]*sol[b];
            for(i=0; i<DIM; i++)
            {
                tmp1 = mvb*r[b][i];
                for(j=0; j<DIM; j++)
                {
                    rmdf[i][j] += tmp1*r[b][j];
                }
            }
        } /* 23 ncons flops */
    }
}