示例#1
0
static void *open_tng_write(const char *filename, const char*,
                            int natoms)
{
    tngdata *tng;
    tng_function_status stat;
//     int64_t n, exp;

    tng = new tngdata;

    stat = tng_util_trajectory_open(filename, 'w', &tng->tng_traj);
    if(stat != TNG_SUCCESS)
    {
        fprintf(stderr, "tngplugin) Cannot open file '%s'\n", filename);
        return NULL;
    }

    tng->natoms = natoms;
    tng->step = 0;
    tng->coord_exponential = -10;
    tng_distance_unit_exponential_set(tng->tng_traj, -10);

    tng->time_per_frame = -1;

    return tng;
}
示例#2
0
static void *open_tng_read(const char *filename, const char*,
                           int *natoms)
{
    tngdata *tng;
    tng_function_status stat;
    int64_t n, exp;

    tng = new tngdata;

    stat = tng_util_trajectory_open(filename, 'r', &tng->tng_traj);
    if(stat != TNG_SUCCESS)
    {
        fprintf(stderr, "tngplugin) Cannot open file '%s'\n", filename);
        return NULL;
    }

    tng_num_particles_get(tng->tng_traj, &n);
    *natoms = (int)n;
    tng->natoms = (int)n;
    tng->step = 0;
    tng_num_frames_get(tng->tng_traj, &n);
    tng->n_frames = n;
    tng->has_velocities = 0;

    tng_distance_unit_exponential_get(tng->tng_traj, &exp);
    tng->coord_exponential = (int) exp;


    return tng;
}
示例#3
0
void gmx_tng_open(const char       *filename,
                  char              mode,
                  tng_trajectory_t *tng)
{
#ifdef GMX_USE_TNG
    /* First check whether we have to make a backup,
     * only for writing, not for read or append.
     */
    if (mode == 'w')
    {
#ifndef GMX_FAHCORE
        /* only make backups for normal gromacs */
        make_backup(filename);
#endif
    }

    /* tng must not be pointing at already allocated memory.
     * Memory will be allocated by tng_util_trajectory_open() and must
     * later on be freed by tng_util_trajectory_close(). */
    if (TNG_SUCCESS != tng_util_trajectory_open(filename, mode, tng))
    {
        /* TNG does return more than one degree of error, but there is
           no use case for GROMACS handling the non-fatal errors
           gracefully. */
        gmx_fatal(FARGS,
                  "%s while opening %s for %s",
                  gmx_strerror("file"),
                  filename,
                  modeToVerb(mode));
    }

    if (mode == 'w' || mode == 'a')
    {
        /* FIXME in TNG: When adding data to the header, subsequent blocks might get
         * overwritten. This could be solved by moving the first trajectory
         * frame set(s) to the end of the file. Could that cause other problems,
         * e.g. when continuing a simulation? */
        char hostname[256];
        gmx_gethostname(hostname, 256);
        if (mode == 'w')
        {
            tng_first_computer_name_set(*tng, hostname);
        }
/* TODO: This should be implemented when the above fixme is done (adding data to
 * the header). */
//         else
//         {
//             tng_last_computer_name_set(*tng, hostname);
//         }

        char        programInfo[256];
        const char *precisionString = "";
#ifdef GMX_DOUBLE
        precisionString = " (double precision)";
#endif
        sprintf(programInfo, "%.100s, %.128s%.24s",
                gmx::getProgramContext().displayName(),
                GromacsVersion(), precisionString);
        if (mode == 'w')
        {
            tng_first_program_name_set(*tng, programInfo);
        }
/* TODO: This should be implemented when the above fixme is done (adding data to
 * the header). */
//         else
//         {
//             tng_last_program_name_set(*tng, programInfo);
//         }

#ifdef HAVE_UNISTD_H
        char username[256];
        getlogin_r(username, 256);
        if (mode == 'w')
        {
            tng_first_user_name_set(*tng, username);
        }
/* TODO: This should be implemented when the above fixme is done (adding data to
 * the header). */
//         else
//         {
//             tng_last_user_name_set(*tng, username);
//         }
#endif
    }
#else
    gmx_file("GROMACS was compiled without TNG support, cannot handle this file type");
    GMX_UNUSED_VALUE(filename);
    GMX_UNUSED_VALUE(mode);
    GMX_UNUSED_VALUE(tng);
#endif
}
示例#4
0
int main ()

/******************************************************************************/
/*
    Purpose:

        MAIN is the main program for MD_OPENMP.

    Discussion:

        MD implements a simple molecular dynamics simulation.

        The program uses Open MP directives to allow parallel computation.

        The velocity Verlet time integration scheme is used.

        The particles interact with a central pair potential.

        Output of the program is saved in the TNG format, which is why this
        code is included in the TNG API release. The high-level API of the
        TNG API is used where appropriate.

    Licensing:

        This code is distributed under the GNU LGPL license.

    Modified:

        8 Jan 2013

    Author:

        Original FORTRAN77 version by Bill Magro.
        C version by John Burkardt.
        TNG trajectory output by Magnus Lundborg.

    Parameters:

        None
*/
{
    float *acc;
    float *box;
    float *box_shape;
    float dt = 0.0002;
    float e0;
    float *force;
    int i;
    float kinetic;
    float mass = 1.0;
    int nd = 3;
    int np = 50;
    float *pos;
    float potential;
    int proc_num;
    int seed = 123456789;
    int step;
    int step_num = 50000;
    int step_print;
    int step_print_index;
    int step_print_num;
    int step_save;
    float *vel;
    float wtime;
    tng_trajectory_t traj;
    tng_molecule_t molecule;
    tng_chain_t chain;
    tng_residue_t residue;
    tng_atom_t atom;

    timestamp ( );

    proc_num = omp_get_num_procs ( );

    acc = ( float * ) malloc ( nd * np * sizeof ( float ) );
    box = ( float * ) malloc ( nd * sizeof ( float ) );
    box_shape = (float *) malloc (9 * sizeof (float));
    force = ( float * ) malloc ( nd * np * sizeof ( float ) );
    pos = ( float * ) malloc ( nd * np * sizeof ( float ) );
    vel = ( float * ) malloc ( nd * np * sizeof ( float ) );

    printf ( "\n" );
    printf ( "MD_OPENMP\n" );
    printf ( "  C/OpenMP version\n" );
    printf ( "\n" );
    printf ( "  A molecular dynamics program.\n" );

    printf ( "\n" );
    printf ( "  NP, the number of particles in the simulation is %d\n", np );
    printf ( "  STEP_NUM, the number of time steps, is %d\n", step_num );
    printf ( "  DT, the size of each time step, is %f\n", dt );

    printf ( "\n" );
    printf ( "  Number of processors available = %d\n", proc_num );
    printf ( "  Number of threads =              %d\n", omp_get_max_threads ( ) );


    printf("\n");
    printf("  Initializing trajectory storage.\n");
    /* Initialize the TNG trajectory */
    tng_util_trajectory_open(TNG_EXAMPLE_FILES_DIR "tng_md_out.tng", 'w', &traj);



    /* Set molecules data */
    /* N.B. This is still not done using utility functions. The low-level API
     * is used. */
    printf("  Creating molecules in trajectory.\n");
    tng_molecule_add(traj, "water", &molecule);
    tng_molecule_chain_add(traj, molecule, "W", &chain);
    tng_chain_residue_add(traj, chain, "WAT", &residue);
    if(tng_residue_atom_add(traj, residue, "O", "O", &atom) == TNG_CRITICAL)
    {
        tng_util_trajectory_close(&traj);
        printf("  Cannot create molecules.\n");
        exit(1);
    }
    tng_molecule_cnt_set(traj, molecule, np);


/*
    Set the dimensions of the box.
*/
    for(i = 0; i < 9; i++)
    {
        box_shape[i] = 0.0;
    }
    for ( i = 0; i < nd; i++ )
    {
        box[i] = 10.0;
        /* box_shape stores 9 values according to the TNG specs */
        box_shape[i*nd + i] = box[i];
    }


    printf ( "\n" );
    printf ( "  Initializing positions, velocities, and accelerations.\n" );
/*
    Set initial positions, velocities, and accelerations.
*/
    initialize ( np, nd, box, &seed, pos, vel, acc );
/*
    Compute the forces and energies.
*/
    printf ( "\n" );
    printf ( "  Computing initial forces and energies.\n" );

    compute ( np, nd, pos, vel, mass, force, &potential, &kinetic );

    e0 = potential + kinetic;

    /* Saving frequency */
    step_save = 400;

    step_print = 0;
    step_print_index = 0;
    step_print_num = 10;

/*
    This is the main time stepping loop:
        Compute forces and energies,
        Update positions, velocities, accelerations.
*/
    printf("  Every %d steps box shape, particle positions, velocities and forces are\n",
           step_save);
    printf("  saved to a TNG trajectory file.\n");
    printf ( "\n" );
    printf ( "  At certain step intervals, we report the potential and kinetic energies.\n" );
    printf ( "  The sum of these energies should be a constant.\n" );
    printf ( "  As an accuracy check, we also print the relative error\n" );
    printf ( "  in the total energy.\n" );
    printf ( "\n" );
    printf ( "      Step      Potential       Kinetic        (P+K-E0)/E0\n" );
    printf ( "                Energy P        Energy K       Relative Energy Error\n" );
    printf ( "\n" );

    step = 0;
    printf ( "  %8d  %14f  %14f  %14e\n",
        step, potential, kinetic, ( potential + kinetic - e0 ) / e0 );
    step_print_index++;
    step_print = ( step_print_index * step_num ) / step_print_num;

    /* Set the output frequency of box shape, positions, velocities and forces */
    if(tng_util_box_shape_write_frequency_set(traj, step_save) != TNG_SUCCESS)
    {
        printf("Error setting writing frequency data. %s: %d\n",
               __FILE__, __LINE__);
        exit(1);
    }
    if(tng_util_pos_write_frequency_set(traj, step_save) != TNG_SUCCESS)
    {
        printf("Error setting writing frequency data. %s: %d\n",
               __FILE__, __LINE__);
        exit(1);
    }
    if(tng_util_vel_write_frequency_set(traj, step_save) != TNG_SUCCESS)
    {
        printf("Error setting writing frequency data. %s: %d\n",
               __FILE__, __LINE__);
        exit(1);
    }
    if(tng_util_force_write_frequency_set(traj, step_save) != TNG_SUCCESS)
    {
        printf("Error setting writing frequency data. %s: %d\n",
               __FILE__, __LINE__);
        exit(1);
    }

    /* Write the first frame of box shape, positions, velocities and forces */
    if(tng_util_box_shape_write(traj, 0, box_shape) != TNG_SUCCESS)
    {
        printf("Error writing box shape. %s: %d\n",
               __FILE__, __LINE__);
        exit(1);
    }
    if(tng_util_pos_write(traj, 0, pos) != TNG_SUCCESS)
    {
        printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
        exit(1);
    }
    if(tng_util_vel_write(traj, 0, vel) != TNG_SUCCESS)
    {
        printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
        exit(1);
    }
    if(tng_util_force_write(traj, 0, force) != TNG_SUCCESS)
    {
        printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
        exit(1);
    }

    wtime = omp_get_wtime ( );

    for ( step = 1; step < step_num; step++ )
    {
        compute ( np, nd, pos, vel, mass, force, &potential, &kinetic );

        if ( step == step_print )
        {
            printf ( "  %8d  %14f  %14f  %14e\n", step, potential, kinetic,
             ( potential + kinetic - e0 ) / e0 );
            step_print_index++;
            step_print = ( step_print_index * step_num ) / step_print_num;
        }
        if(step % step_save == 0)
        {
            /* Write box shape, positions, velocities and forces */
            if(tng_util_box_shape_write(traj, step, box_shape) != TNG_SUCCESS)
            {
                printf("Error writing box shape. %s: %d\n",
                       __FILE__, __LINE__);
                exit(1);
            }
            if(tng_util_pos_write(traj, step, pos) != TNG_SUCCESS)
            {
                printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
                break;
            }
            if(tng_util_vel_write(traj, step, vel) != TNG_SUCCESS)
            {
                printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
                break;
            }
            if(tng_util_force_write(traj, step, force) != TNG_SUCCESS)
            {
                printf("Error adding data. %s: %d\n", __FILE__, __LINE__);
                break;
            }
        }
        update ( np, nd, pos, vel, force, acc, mass, dt );
    }
    wtime = omp_get_wtime ( ) - wtime;

    printf ( "\n" );
    printf ( "  Elapsed time for main computation:\n" );
    printf ( "  %f seconds.\n", wtime );

    free ( acc );
    free ( box );
    free ( box_shape );
    free ( force );
    free ( pos );
    free ( vel );

    /* Close the TNG output. */
    tng_util_trajectory_close(&traj);

    printf ( "\n" );
    printf ( "MD_OPENMP\n" );
    printf ( "  Normal end of execution.\n" );

    printf ( "\n" );
    timestamp ( );

    return 0;
}