示例#1
0
static void rand_rot(int natoms, rvec x[], rvec v[], vec4 xrot[], vec4 vrot[],
                     gmx::DefaultRandomEngine * rng, rvec max_rot)
{
    mat4 mt1, mt2, mr[DIM], mtemp1, mtemp2, mtemp3, mxtot, mvtot;
    rvec xcm;
    real phi;
    int  i, m;
    gmx::UniformRealDistribution<real> dist(-1.0, 1.0);

    clear_rvec(xcm);
    for (i = 0; (i < natoms); i++)
    {
        for (m = 0; (m < DIM); m++)
        {
            xcm[m] += x[i][m]/natoms; /* get center of mass of one molecule  */
        }
    }
    fprintf(stderr, "center of geometry: %f, %f, %f\n", xcm[0], xcm[1], xcm[2]);

    /* move c.o.ma to origin */
    gmx_mat4_init_translation(-xcm[XX], -xcm[YY], -xcm[ZZ], mt1);
    for (m = 0; (m < DIM); m++)
    {
        phi = M_PI*max_rot[m]*dist(*rng)/180;
        gmx_mat4_init_rotation(m, phi, mr[m]);
    }
    gmx_mat4_init_translation(xcm[XX], xcm[YY], xcm[ZZ], mt2);

    /* For gmx_mat4_mmul() we need to multiply in the opposite order
     * compared to normal mathematical notation.
     */
    gmx_mat4_mmul(mtemp1, mt1, mr[XX]);
    gmx_mat4_mmul(mtemp2, mr[YY], mr[ZZ]);
    gmx_mat4_mmul(mtemp3, mtemp1, mtemp2);
    gmx_mat4_mmul(mxtot, mtemp3, mt2);
    gmx_mat4_mmul(mvtot, mr[XX], mtemp2);

    for (i = 0; (i < natoms); i++)
    {
        gmx_mat4_transform_point(mxtot, x[i], xrot[i]);
        gmx_mat4_transform_point(mvtot, v[i], vrot[i]);
    }
}
示例#2
0
static void rot_conf(t_atoms *atoms, rvec x[], rvec v[], real trans, real angle,
                     rvec head, rvec tail, int isize, atom_id index[],
                     rvec xout[], rvec vout[])
{
    rvec     arrow, xcm;
    real     theta, phi, arrow_len;
    mat4     Rx, Ry, Rz, Rinvy, Rinvz, Mtot;
    mat4     temp1, temp2, temp3;
    vec4     xv;
    int      i, ai;

    rvec_sub(tail, head, arrow);
    arrow_len = norm(arrow);
    if (debug)
    {
        fprintf(debug, "Arrow vector:   %10.4f  %10.4f  %10.4f\n",
                arrow[XX], arrow[YY], arrow[ZZ]);
        fprintf(debug, "Effective translation %g nm\n", trans);
    }
    if (arrow_len == 0.0)
    {
        gmx_fatal(FARGS, "Arrow vector not given");
    }

    /* Copy all aoms to output */
    for (i = 0; (i < atoms->nr); i++)
    {
        copy_rvec(x[i], xout[i]);
        copy_rvec(v[i], vout[i]);
    }

    /* Compute center of mass and move atoms there */
    clear_rvec(xcm);
    for (i = 0; (i < isize); i++)
    {
        rvec_inc(xcm, x[index[i]]);
    }
    for (i = 0; (i < DIM); i++)
    {
        xcm[i] /= isize;
    }
    if (debug)
    {
        fprintf(debug, "Center of mass: %10.4f  %10.4f  %10.4f\n",
                xcm[XX], xcm[YY], xcm[ZZ]);
    }
    for (i = 0; (i < isize); i++)
    {
        rvec_sub(x[index[i]], xcm, xout[index[i]]);
    }

    /* Compute theta and phi that describe the arrow */
    theta = std::acos(arrow[ZZ]/arrow_len);
    phi   = std::atan2(arrow[YY]/arrow_len, arrow[XX]/arrow_len);
    if (debug)
    {
        fprintf(debug, "Phi = %.1f, Theta = %.1f\n", RAD2DEG*phi, RAD2DEG*theta);
    }

    /* Now the total rotation matrix: */
    /* Rotate a couple of times */
    gmx_mat4_init_rotation(ZZ, -phi, Rz);
    gmx_mat4_init_rotation(YY, M_PI/2-theta, Ry);
    gmx_mat4_init_rotation(XX, angle*DEG2RAD, Rx);
    Rx[WW][XX] = trans;
    gmx_mat4_init_rotation(YY, theta-M_PI/2, Rinvy);
    gmx_mat4_init_rotation(ZZ, phi, Rinvz);

    gmx_mat4_mmul(temp1, Ry, Rz);
    gmx_mat4_mmul(temp2, Rinvy, Rx);
    gmx_mat4_mmul(temp3, temp2, temp1);
    gmx_mat4_mmul(Mtot, Rinvz, temp3);

    if (debug)
    {
        gmx_mat4_print(debug, "Rz", Rz);
        gmx_mat4_print(debug, "Ry", Ry);
        gmx_mat4_print(debug, "Rx", Rx);
        gmx_mat4_print(debug, "Rinvy", Rinvy);
        gmx_mat4_print(debug, "Rinvz", Rinvz);
        gmx_mat4_print(debug, "Mtot", Mtot);
    }

    for (i = 0; (i < isize); i++)
    {
        ai = index[i];
        gmx_mat4_transform_point(Mtot, xout[ai], xv);
        rvec_add(xv, xcm, xout[ai]);
        gmx_mat4_transform_point(Mtot, v[ai], xv);
        copy_rvec(xv, vout[ai]);
    }
}