Beispiel #1
0
/******************Public functions**********************/
void System::simulate(double tMax, double ssize, bool stat){
    time = 0;
    h = ssize;
    statSun = stat;
    for (int i = 0 ; i<nObj ; i++){ // Saveing the inital values
        calc_potential();
        sys[i].update(sys[i].relR, sys[i].relV, time);
    }
    while (time <= tMax){
        RK4();
        time += h;
    }
}
Beispiel #2
0
// Runge-Kutta 4 algorithm
void System::RK4(){
    vec2dN K1(nObj), K2(nObj), K3(nObj), K4(nObj);
    vec2dN L1(nObj), L2(nObj), L3(nObj), L4(nObj);

    vec2dN NewR(nObj), NewV(nObj);
    if (nObj == 1){ // If only ONE object
        K1 = h*derX(vec2dN(nObj));
        L1 = h*(SunInf(vec2dN(nObj)));
        K2 = h*derX(L1*0.5);
        L2 = h*(SunInf(K1*0.5));
        K3 = h*derX(L2*0.5);
        L3 = h*(SunInf(K2*0.5));
        K4 = h*derX(L3);
        L4 = h*(SunInf(K3));
    } else { // If more than one object
        if (!statSun){ // Sun mobile or not pressent
            K1 = h*derX(vec2dN(nObj));
            L1 = h*derV(vec2dN(nObj));
            K2 = h*derX(L1*0.5);
            L2 = h*derV(K1*0.5);
            K3 = h*derX(L2*0.5);
            L3 = h*derV(L2*0.5);
            K4 = h*derX(L3);
            L4 = h*derV(K4);
        } else { // If the sun is stationary
            K1 = h*derX(vec2dN(nObj));
            L1 = h*(derV(vec2dN(nObj)) + SunInf(vec2dN(nObj)));
            K2 = h*derX(L1*0.5);
            L2 = h*(derV(K1*0.5) + SunInf(K1*0.5));
            K3 = h*derX(L2*0.5);
            L3 = h*(derV(K2*0.5) + SunInf(K2*0.5));
            K4 = h*derX(L3);
            L4 = h*(derV(K3) + SunInf(K3));
        }
    }
    for (int i = 0 ; i < nObj ; i++){
        NewR[i] = sys[i].relR + (K1[i] + 2*K2[i] + 2*K3[i] + K4[i])/(double)6;
        NewV[i] = sys[i].relV + (L1[i] + 2*L2[i] + 2*L3[i] + L4[i])/(double)6;
    }
    calc_potential();
    for (int i = 0 ; i < nObj ; i++){
        sys[i].update(NewR[i], NewV[i], sys[i].relT+h);
    }
}
int gmx_potential(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] computes the electrostatical potential across the box. The potential is",
        "calculated by first summing the charges per slice and then integrating",
        "twice of this charge distribution. Periodic boundaries are not taken",
        "into account. Reference of potential is taken to be the left side of",
        "the box. It is also possible to calculate the potential in spherical",
        "coordinates as function of r by calculating a charge distribution in",
        "spherical slices and twice integrating them. epsilon_r is taken as 1,",
        "but 2 is more appropriate in many cases."
    };
    gmx_output_env_t  *oenv;
    static int         axis       = 2;       /* normal to memb. default z  */
    static const char *axtitle    = "Z";
    static int         nslices    = 10;      /* nr of slices defined       */
    static int         ngrps      = 1;
    static gmx_bool    bSpherical = FALSE;   /* default is bilayer types   */
    static real        fudge_z    = 0;       /* translate coordinates      */
    static gmx_bool    bCorrect   = 0;
    t_pargs            pa []      = {
        { "-d",   FALSE, etSTR, {&axtitle},
          "Take the normal on the membrane in direction X, Y or Z." },
        { "-sl",  FALSE, etINT, {&nslices},
          "Calculate potential as function of boxlength, dividing the box"
          " in this number of slices." },
        { "-cb",  FALSE, etINT, {&cb},
          "Discard this number of  first slices of box for integration" },
        { "-ce",  FALSE, etINT, {&ce},
          "Discard this number of last slices of box for integration" },
        { "-tz",  FALSE, etREAL, {&fudge_z},
          "Translate all coordinates by this distance in the direction of the box" },
        { "-spherical", FALSE, etBOOL, {&bSpherical},
          "Calculate spherical thingie" },
        { "-ng",       FALSE, etINT, {&ngrps},
          "Number of groups to consider" },
        { "-correct",  FALSE, etBOOL, {&bCorrect},
          "Assume net zero charge of groups to improve accuracy" }
    };
    const char        *bugs[] = {
        "Discarding slices for integration should not be necessary."
    };

    double           **potential,              /* potential per slice        */
    **charge,                                  /* total charge per slice     */
    **field,                                   /* field per slice            */
                       slWidth;                /* width of one slice         */
    char      **grpname;                       /* groupnames                 */
    int        *ngx;                           /* sizes of groups            */
    t_topology *top;                           /* topology        */
    int         ePBC;
    int       **index;                         /* indices for all groups     */
    t_filenm    fnm[] = {                      /* files for g_order       */
        { efTRX, "-f", NULL,  ffREAD },        /* trajectory file             */
        { efNDX, NULL, NULL,  ffREAD },        /* index file          */
        { efTPR, NULL, NULL,  ffREAD },        /* topology file               */
        { efXVG, "-o", "potential", ffWRITE }, /* xvgr output file    */
        { efXVG, "-oc", "charge", ffWRITE },   /* xvgr output file    */
        { efXVG, "-of", "field", ffWRITE },    /* xvgr output file    */
    };

#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs,
                           &oenv))
    {
        return 0;
    }

    /* Calculate axis */
    axis = toupper(axtitle[0]) - 'X';

    top = read_top(ftp2fn(efTPR, NFILE, fnm), &ePBC); /* read topology file */

    snew(grpname, ngrps);
    snew(index, ngrps);
    snew(ngx, ngrps);

    rd_index(ftp2fn(efNDX, NFILE, fnm), ngrps, ngx, index, grpname);


    calc_potential(ftp2fn(efTRX, NFILE, fnm), index, ngx,
                   &potential, &charge, &field,
                   &nslices, top, ePBC, axis, ngrps, &slWidth, fudge_z,
                   bSpherical, bCorrect, oenv);

    plot_potential(potential, charge, field, opt2fn("-o", NFILE, fnm),
                   opt2fn("-oc", NFILE, fnm), opt2fn("-of", NFILE, fnm),
                   nslices, ngrps, (const char**)grpname, slWidth, oenv);

    do_view(oenv, opt2fn("-o", NFILE, fnm), NULL);  /* view xvgr file */
    do_view(oenv, opt2fn("-oc", NFILE, fnm), NULL); /* view xvgr file */
    do_view(oenv, opt2fn("-of", NFILE, fnm), NULL); /* view xvgr file */

    return 0;
}