Ejemplo n.º 1
0
static int write_tng_structure(void *v, int optflags, const molfile_atom_t *atoms)
{
    /* VMD atoms do not contain molecule information, which
     * complicates TNG writing a bit. */
    tng_molecule_t tng_mol;
    tng_chain_t tng_chain;
    tng_residue_t tng_residue;
    tng_atom_t tng_atom;

    tngdata *tng = (tngdata *)v;

    /* A dummy molecule must be added. All atoms will be added to it. */
    tng_molecule_add(tng->tng_traj, "MOL", &tng_mol);
    for(int i = 0; i < tng->natoms; i++)
    {
        if(tng_molecule_chain_find(tng->tng_traj, tng_mol, atoms[i].chain, -1, &tng_chain) !=
            TNG_SUCCESS)
        {
            tng_molecule_chain_add(tng->tng_traj, tng_mol, atoms[i].chain, &tng_chain);
        }
        if (tng_chain_residue_find(tng->tng_traj, tng_chain, atoms[i].resname,
                                   atoms[i].resid, &tng_residue) != TNG_SUCCESS)
        {
            tng_chain_residue_w_id_add(tng->tng_traj, tng_chain, atoms[i].resname,
                                       atoms[i].resid, &tng_residue);
        }
        tng_residue_atom_add(tng->tng_traj, tng_residue, atoms[i].name, atoms[i].type, &tng_atom);
    }

    return MOLFILE_SUCCESS;
}
Ejemplo n.º 2
0
static void addTngMoleculeFromTopology(tng_trajectory_t     tng,
                                       const char          *moleculeName,
                                       const t_atoms       *atoms,
                                       gmx_int64_t          numMolecules,
                                       tng_molecule_t      *tngMol)
{
    if (tng_molecule_add(tng, moleculeName, tngMol) != TNG_SUCCESS)
    {
        gmx_file("Cannot add molecule to TNG molecular system.");
    }

    /* FIXME: The TNG atoms should contain mass and atomB info (for free
     * energy calculations), i.e. in when it's available in TNG (2.0). */
    for (int atomIt = 0; atomIt < atoms->nr; atomIt++)
    {
        const t_atom *at = &atoms->atom[atomIt];
        /* FIXME: Currently the TNG API can only add atoms belonging to a
         * residue and chain. Wait for TNG 2.0*/
        if (atoms->nres > 0)
        {
            const t_resinfo *resInfo        = &atoms->resinfo[at->resind];
            char             chainName[2]   = {resInfo->chainid, 0};
            tng_chain_t      tngChain       = NULL;
            tng_residue_t    tngRes         = NULL;
            tng_atom_t       tngAtom        = NULL;

            if (tng_molecule_chain_find (tng, *tngMol, chainName,
                                         (gmx_int64_t)-1, &tngChain) !=
                TNG_SUCCESS)
            {
                tng_molecule_chain_add (tng, *tngMol, chainName,
                                        &tngChain);
            }

            /* FIXME: When TNG supports both residue index and residue
             * number the latter should be used. Wait for TNG 2.0*/
            if (tng_chain_residue_find(tng, tngChain, *resInfo->name,
                                       at->resind + 1, &tngRes)
                != TNG_SUCCESS)
            {
                tng_chain_residue_add(tng, tngChain, *resInfo->name, &tngRes);
            }
            tng_residue_atom_add(tng, tngRes, *(atoms->atomname[atomIt]), *(atoms->atomtype[atomIt]), &tngAtom);
        }
    }
    tng_molecule_cnt_set(tng, *tngMol, numMolecules);
}
Ejemplo n.º 3
0
/* Create a TNG molecule representing the selection groups
 * to write */
static void add_selection_groups(tng_trajectory_t  tng,
                                 const gmx_mtop_t *mtop)
{
    const gmx_moltype_t     *molType;
    const t_atoms           *atoms;
    const t_atom            *at;
    const t_resinfo         *resInfo;
    const t_ilist           *ilist;
    int                      nAtoms      = 0, i = 0, j, molIt, atomIt, nameIndex;
    int                      atom_offset = 0;
    tng_molecule_t           mol, iterMol;
    tng_chain_t              chain;
    tng_residue_t            res;
    tng_atom_t               atom;
    tng_bond_t               tngBond;
    gmx_int64_t              nMols;
    char                    *groupName;

    /* The name of the TNG molecule containing the selection group is the
     * same as the name of the selection group. */
    nameIndex = *mtop->groups.grps[egcCompressedX].nm_ind;
    groupName = *mtop->groups.grpname[nameIndex];

    tng_molecule_alloc(tng, &mol);
    tng_molecule_name_set(tng, mol, groupName);
    tng_molecule_chain_add(tng, mol, "", &chain);
    for (molIt = 0; molIt < mtop->nmoltype; molIt++)
    {
        molType = &mtop->moltype[mtop->molblock[molIt].type];

        atoms = &molType->atoms;

        for (j = 0; j < mtop->molblock[molIt].nmol; j++)
        {
            bool bAtomsAdded = FALSE;
            for (atomIt = 0; atomIt < atoms->nr; atomIt++, i++)
            {
                char *res_name;
                int   res_id;

                if (ggrpnr(&mtop->groups, egcCompressedX, i) != 0)
                {
                    continue;
                }
                at = &atoms->atom[atomIt];
                if (atoms->nres > 0)
                {
                    resInfo = &atoms->resinfo[at->resind];
                    /* FIXME: When TNG supports both residue index and residue
                     * number the latter should be used. */
                    res_name = *resInfo->name;
                    res_id   = at->resind + 1;
                }
                else
                {
                    res_name = (char *)"";
                    res_id   = 0;
                }
                if (tng_chain_residue_find(tng, chain, res_name, res_id, &res)
                    != TNG_SUCCESS)
                {
                    /* Since there is ONE chain for selection groups do not keep the
                     * original residue IDs - otherwise there might be conflicts. */
                    tng_chain_residue_add(tng, chain, res_name, &res);
                }
                tng_residue_atom_w_id_add(tng, res, *(atoms->atomname[atomIt]),
                                          *(atoms->atomtype[atomIt]),
                                          atom_offset + atomIt, &atom);
                nAtoms++;
                bAtomsAdded = TRUE;
            }
            /* Add bonds. */
            if (bAtomsAdded)
            {
                for (int k = 0; k < F_NRE; k++)
                {
                    if (IS_CHEMBOND(k))
                    {
                        ilist = &molType->ilist[k];
                        if (ilist)
                        {
                            int l = 1;
                            while (l < ilist->nr)
                            {
                                int atom1, atom2;
                                atom1 = ilist->iatoms[l] + atom_offset;
                                atom2 = ilist->iatoms[l+1] + atom_offset;
                                if (ggrpnr(&mtop->groups, egcCompressedX, atom1) == 0 &&
                                    ggrpnr(&mtop->groups, egcCompressedX, atom2) == 0)
                                {
                                    tng_molecule_bond_add(tng, mol, ilist->iatoms[l],
                                                          ilist->iatoms[l+1], &tngBond);
                                }
                                l += 3;
                            }
                        }
                    }
                }
                /* Settle is described using three atoms */
                ilist = &molType->ilist[F_SETTLE];
                if (ilist)
                {
                    int l = 1;
                    while (l < ilist->nr)
                    {
                        int atom1, atom2, atom3;
                        atom1 = ilist->iatoms[l] + atom_offset;
                        atom2 = ilist->iatoms[l+1] + atom_offset;
                        atom3 = ilist->iatoms[l+2] + atom_offset;
                        if (ggrpnr(&mtop->groups, egcCompressedX, atom1) == 0)
                        {
                            if (ggrpnr(&mtop->groups, egcCompressedX, atom2) == 0)
                            {
                                tng_molecule_bond_add(tng, mol, atom1,
                                                      atom2, &tngBond);
                            }
                            if (ggrpnr(&mtop->groups, egcCompressedX, atom3) == 0)
                            {
                                tng_molecule_bond_add(tng, mol, atom1,
                                                      atom3, &tngBond);
                            }
                        }
                        l += 4;
                    }
                }
            }
            atom_offset += atoms->nr;
        }
    }
    if (nAtoms != i)
    {
        tng_molecule_existing_add(tng, &mol);
        tng_molecule_cnt_set(tng, mol, 1);
        tng_num_molecule_types_get(tng, &nMols);
        for (gmx_int64_t k = 0; k < nMols; k++)
        {
            tng_molecule_of_index_get(tng, k, &iterMol);
            if (iterMol == mol)
            {
                continue;
            }
            tng_molecule_cnt_set(tng, iterMol, 0);
        }
    }
    else
    {
        tng_molecule_free(tng, &mol);
    }
}
Ejemplo n.º 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;
}
Ejemplo n.º 5
0
void gmx_tng_setup_atom_subgroup(tng_trajectory_t tng,
                                 const int        nind,
                                 const int       *ind,
                                 const char      *name)
{
#if GMX_USE_TNG
    gmx_int64_t              nAtoms, cnt, nMols;
    tng_molecule_t           mol, iterMol;
    tng_chain_t              chain;
    tng_residue_t            res;
    tng_atom_t               atom;
    tng_function_status      stat;

    tng_num_particles_get(tng, &nAtoms);

    if (nAtoms == nind)
    {
        return;
    }

    stat = tng_molecule_find(tng, name, -1, &mol);
    if (stat == TNG_SUCCESS)
    {
        tng_molecule_num_atoms_get(tng, mol, &nAtoms);
        tng_molecule_cnt_get(tng, mol, &cnt);
        if (nAtoms == nind)
        {
            stat = TNG_SUCCESS;
        }
        else
        {
            stat = TNG_FAILURE;
        }
    }
    if (stat == TNG_FAILURE)
    {
        /* The indexed atoms are added to one separate molecule. */
        tng_molecule_alloc(tng, &mol);
        tng_molecule_name_set(tng, mol, name);
        tng_molecule_chain_add(tng, mol, "", &chain);

        for (int i = 0; i < nind; i++)
        {
            char        temp_name[256], temp_type[256];

            /* Try to retrieve the residue name of the atom */
            stat = tng_residue_name_of_particle_nr_get(tng, ind[i], temp_name, 256);
            if (stat != TNG_SUCCESS)
            {
                temp_name[0] = '\0';
            }
            /* Check if the molecule of the selection already contains this residue */
            if (tng_chain_residue_find(tng, chain, temp_name, -1, &res)
                != TNG_SUCCESS)
            {
                tng_chain_residue_add(tng, chain, temp_name, &res);
            }
            /* Try to find the original name and type of the atom */
            stat = tng_atom_name_of_particle_nr_get(tng, ind[i], temp_name, 256);
            if (stat != TNG_SUCCESS)
            {
                temp_name[0] = '\0';
            }
            stat = tng_atom_type_of_particle_nr_get(tng, ind[i], temp_type, 256);
            if (stat != TNG_SUCCESS)
            {
                temp_type[0] = '\0';
            }
            tng_residue_atom_w_id_add(tng, res, temp_name, temp_type, ind[i], &atom);
        }
        tng_molecule_existing_add(tng, &mol);
    }
    /* Set the count of the molecule containing the selected atoms to 1 and all
     * other molecules to 0 */
    tng_molecule_cnt_set(tng, mol, 1);
    tng_num_molecule_types_get(tng, &nMols);
    for (gmx_int64_t k = 0; k < nMols; k++)
    {
        tng_molecule_of_index_get(tng, k, &iterMol);
        if (iterMol == mol)
        {
            continue;
        }
        tng_molecule_cnt_set(tng, iterMol, 0);
    }
#else
    GMX_UNUSED_VALUE(tng);
    GMX_UNUSED_VALUE(nind);
    GMX_UNUSED_VALUE(ind);
    GMX_UNUSED_VALUE(name);
#endif
}