示例#1
0
void UpdateGroupsCog::addCogs(gmx::ArrayRef<const int>        globalAtomIndices,
                              gmx::ArrayRef<const gmx::RVec>  coordinates)
{
    const int    localAtomBegin = cogIndices_.size();
    const size_t cogBegin       = cogs_.size();

    GMX_RELEASE_ASSERT(globalAtomIndices.size() >= localAtomBegin,
                       "addCogs should only be called to add COGs to the list that is already present (which could be empty)");

    cogIndices_.reserve(globalAtomIndices.size());

    int moleculeBlock = 0;
    for (int localAtom = localAtomBegin; localAtom < globalAtomIndices.size(); localAtom++)
    {
        const int   globalAtom = globalAtomIndices[localAtom];
        int         moleculeIndex;
        int         atomIndexInMolecule;
        mtopGetMolblockIndex(&mtop_, globalAtom,
                             &moleculeBlock, &moleculeIndex, &atomIndexInMolecule);
        const auto &indicesForBlock        = indicesPerMoleculeblock_[moleculeBlock];
        int         globalUpdateGroupIndex =
            indicesForBlock.groupStart_ +
            moleculeIndex*indicesForBlock.numGroupsPerMolecule_ +
            indicesForBlock.groupIndex_[atomIndexInMolecule];

        if (const int *cogIndexPtr = globalToLocalMap_.find(globalUpdateGroupIndex))
        {
            GMX_ASSERT(static_cast<size_t>(*cogIndexPtr) >= cogBegin,
                       "Added atoms should not be part of previously present groups");

            cogIndices_.push_back(*cogIndexPtr);

            cogs_[*cogIndexPtr] += coordinates[localAtom];
            numAtomsPerCog_[*cogIndexPtr]++;
        }
        else
        {
            const int cogIndex = cogs_.size();

            globalToLocalMap_.insert(globalUpdateGroupIndex, cogIndex);
            cogIndices_.push_back(cogIndex);
            cogs_.push_back(coordinates[localAtom]);
            numAtomsPerCog_.push_back(1);
        }
    }

    /* Divide sum of coordinates for each COG by the number of atoms */
    for (size_t i = cogBegin; i < cogs_.size(); i++)
    {
        const int numAtoms = numAtomsPerCog_[i];
        if (numAtoms > 1)
        {
            cogs_[i] /= numAtoms;
        }
    }
}
示例#2
0
void
ddSendrecv(const gmx_domdec_t *dd,
           int                 ddDimensionIndex,
           int                 direction,
           gmx::ArrayRef<T>    sendBuffer,
           gmx::ArrayRef<T>    receiveBuffer)
{
    ddSendrecv(dd, ddDimensionIndex, direction,
               sendBuffer.data(), sendBuffer.size(),
               receiveBuffer.data(), receiveBuffer.size());
}
示例#3
0
static void sort_files(gmx::ArrayRef<std::string> files, real *settime)
{
    for (gmx::index i = 0; i < files.ssize(); i++)
    {
        gmx::index minidx = i;
        for (gmx::index j = i + 1; j < files.ssize(); j++)
        {
            if (settime[j] < settime[minidx])
            {
                minidx = j;
            }
        }
        if (minidx != i)
        {
            real timeswap   = settime[i];
            settime[i]      = settime[minidx];
            settime[minidx] = timeswap;
            std::swap(files[i], files[minidx]);
        }
    }
}
示例#4
0
static void dd_collect_vec_gatherv(gmx_domdec_t                  *dd,
                                   gmx::ArrayRef<const gmx::RVec> lv,
                                   gmx::ArrayRef<gmx::RVec>       v)
{
    int *recvCounts    = nullptr;
    int *displacements = nullptr;

    if (DDMASTER(dd))
    {
        get_commbuffer_counts(dd->ma.get(), &recvCounts, &displacements);
    }

    const int numHomeAtoms = dd->comm->atomRanges.numHomeAtoms();
    dd_gatherv(dd, numHomeAtoms*sizeof(rvec), lv.data(), recvCounts, displacements,
               DDMASTER(dd) ? dd->ma->rvecBuffer.data() : nullptr);

    if (DDMASTER(dd))
    {
        const AtomDistribution &ma     = *dd->ma;

        const t_block          &cgs_gl = dd->comm->cgs_gl;

        int                     bufferAtom = 0;
        for (int rank = 0; rank < dd->nnodes; rank++)
        {
            const auto &domainGroups = ma.domainGroups[rank];
            for (const int &cg : domainGroups.atomGroups)
            {
                for (int globalAtom = cgs_gl.index[cg]; globalAtom < cgs_gl.index[cg + 1]; globalAtom++)
                {
                    copy_rvec(ma.rvecBuffer[bufferAtom++], v[globalAtom]);
                }
            }
        }
    }
}
示例#5
0
static void scan_trj_files(gmx::ArrayRef<const std::string> files,
                           real *readtime,
                           real *timestep, int imax,
                           const gmx_output_env_t *oenv)
{
    /* Check start time of all files */
    int          natoms = 0;
    t_trxstatus *status;
    t_trxframe   fr;
    bool         ok;

    for (gmx::index i = 0; i < files.ssize(); i++)
    {
        ok = read_first_frame(oenv, &status, files[i].c_str(), &fr, FLAGS);

        if (!ok)
        {
            gmx_fatal(FARGS, "\nCouldn't read frame from file." );
        }
        if (fr.bTime)
        {
            readtime[i] = fr.time;
        }
        else
        {
            readtime[i] = 0;
            fprintf(stderr, "\nWARNING: Couldn't find a time in the frame.\n");
        }

        if (i == 0)
        {
            natoms = fr.natoms;
        }
        else
        {
            if (imax == -1)
            {
                if (natoms != fr.natoms)
                {
                    gmx_fatal(FARGS, "\nDifferent numbers of atoms (%d/%d) in files",
                              natoms, fr.natoms);
                }
            }
            else
            {
                if (fr.natoms <= imax)
                {
                    gmx_fatal(FARGS, "\nNot enough atoms (%d) for index group (%d)",
                              fr.natoms, imax);
                }
            }
        }
        ok = read_next_frame(oenv, status, &fr);
        if (ok && fr.bTime)
        {
            timestep[i] = fr.time - readtime[i];
        }
        else
        {
            timestep[i] = 0;
        }

        close_trx(status);
        if (fr.bX)
        {
            sfree(fr.x);
        }
        if (fr.bV)
        {
            sfree(fr.v);
        }
        if (fr.bF)
        {
            sfree(fr.f);
        }
    }
    fprintf(stderr, "\n");

}
示例#6
0
static void do_demux(gmx::ArrayRef<const std::string> inFiles,
                     gmx::ArrayRef<const std::string> outFiles, int nval,
                     real **value, real *time, real dt_remd, int isize,
                     int index[], real dt, const gmx_output_env_t *oenv)
{
    int           k, natoms;
    t_trxstatus **fp_in, **fp_out;
    gmx_bool      bCont, *bSet;
    real          t, first_time = 0;
    t_trxframe   *trx;

    snew(fp_in, inFiles.size());
    snew(trx, inFiles.size());
    snew(bSet, inFiles.size());
    natoms = -1;
    t      = -1;
    for (gmx::index i = 0; i < inFiles.ssize(); i++)
    {
        read_first_frame(oenv, &(fp_in[i]), inFiles[i].c_str(), &(trx[i]),
                         TRX_NEED_X);
        if (natoms == -1)
        {
            natoms     = trx[i].natoms;
            first_time = trx[i].time;
        }
        else if (natoms != trx[i].natoms)
        {
            gmx_fatal(FARGS, "Trajectory file %s has %d atoms while previous trajs had %d atoms", inFiles[i].c_str(), trx[i].natoms, natoms);
        }
        if (t == -1)
        {
            t = trx[i].time;
        }
        else if (t != trx[i].time)
        {
            gmx_fatal(FARGS, "Trajectory file %s has time %f while previous trajs had time %f", inFiles[i].c_str(), trx[i].time, t);
        }
    }

    snew(fp_out, inFiles.size());
    for (gmx::index i = 0; i < inFiles.ssize(); i++)
    {
        fp_out[i] = open_trx(outFiles[i].c_str(), "w");
    }
    k = 0;
    if (std::round(time[k] - t) != 0)
    {
        gmx_fatal(FARGS, "First time in demuxing table does not match trajectories");
    }
    do
    {
        while ((k+1 < nval) && ((trx[0].time - time[k+1]) > dt_remd*0.1))
        {
            k++;
        }
        if (debug)
        {
            fprintf(debug, "trx[0].time = %g, time[k] = %g\n", trx[0].time, time[k]);
        }
        for (gmx::index i = 0; i < inFiles.ssize(); i++)
        {
            bSet[i] = FALSE;
        }
        for (gmx::index i = 0; i < inFiles.ssize(); i++)
        {
            int j = gmx::roundToInt(value[i][k]);
            range_check(j, 0, inFiles.size());
            if (bSet[j])
            {
                gmx_fatal(FARGS, "Demuxing the same replica %d twice at time %f",
                          j, trx[0].time);
            }
            bSet[j] = TRUE;

            if (dt == 0 || bRmod(trx[i].time, first_time, dt))
            {
                if (index)
                {
                    write_trxframe_indexed(fp_out[j], &trx[i], isize, index, nullptr);
                }
                else
                {
                    write_trxframe(fp_out[j], &trx[i], nullptr);
                }
            }
        }

        bCont = (k < nval);
        for (gmx::index i = 0; i < inFiles.ssize(); i++)
        {
            bCont = bCont && read_next_frame(oenv, fp_in[i], &trx[i]);
        }
    }
    while (bCont);

    for (gmx::index i = 0; i < inFiles.ssize(); i++)
    {
        close_trx(fp_in[i]);
        close_trx(fp_out[i]);
    }
}
示例#7
0
static void edit_files(gmx::ArrayRef<std::string> files,
                       real *readtime, real *timestep,
                       real *settime, int *cont_type, gmx_bool bSetTime,
                       gmx_bool bSort, const gmx_output_env_t *oenv)
{
    gmx_bool ok;
    char     inputstring[STRLEN], *chptr;

    auto     timeUnit = output_env_get_time_unit(oenv);
    if (bSetTime)
    {
        fprintf(stderr, "\n\nEnter the new start time (%s) for each file.\n"
                "There are two special options, both disable sorting:\n\n"
                "c (continue) - The start time is taken from the end\n"
                "of the previous file. Use it when your continuation run\n"
                "restarts with t=0.\n\n"
                "l (last) - The time in this file will be changed the\n"
                "same amount as in the previous. Use it when the time in the\n"
                "new run continues from the end of the previous one,\n"
                "since this takes possible overlap into account.\n\n",
                timeUnit.c_str());

        fprintf(
                stderr,
                "          File             Current start (%s)  New start (%s)\n"
                "---------------------------------------------------------\n",
                timeUnit.c_str(), timeUnit.c_str());

        for (gmx::index i = 0; i < files.ssize(); i++)
        {
            fprintf(stderr, "%25s   %10.3f %s          ", files[i].c_str(),
                    output_env_conv_time(oenv, readtime[i]), timeUnit.c_str());
            ok = FALSE;
            do
            {
                if (nullptr == fgets(inputstring, STRLEN - 1, stdin))
                {
                    gmx_fatal(FARGS, "Error reading user input" );
                }

                inputstring[std::strlen(inputstring)-1] = 0;

                if (inputstring[0] == 'c' || inputstring[0] == 'C')
                {
                    cont_type[i] = TIME_CONTINUE;
                    bSort        = FALSE;
                    ok           = TRUE;
                    settime[i]   = FLT_MAX;
                }
                else if (inputstring[0] == 'l' ||
                         inputstring[0] == 'L')
                {
                    cont_type[i] = TIME_LAST;
                    bSort        = FALSE;
                    ok           = TRUE;
                    settime[i]   = FLT_MAX;
                }
                else
                {
                    settime[i] = strtod(inputstring, &chptr)*
                        output_env_get_time_invfactor(oenv);
                    if (chptr == inputstring)
                    {
                        fprintf(stderr, "'%s' not recognized as a floating point number, 'c' or 'l'. "
                                "Try again: ", inputstring);
                    }
                    else
                    {
                        cont_type[i] = TIME_EXPLICIT;
                        ok           = TRUE;
                    }
                }
            }
            while (!ok);
        }
        if (cont_type[0] != TIME_EXPLICIT)
        {
            cont_type[0] = TIME_EXPLICIT;
            settime[0]   = 0;
        }
    }
    else
    {
        for (gmx::index i = 0; i < files.ssize(); i++)
        {
            settime[i] = readtime[i];
        }
    }
    if (!bSort)
    {
        fprintf(stderr, "Sorting disabled.\n");
    }
    else
    {
        sort_files(files, settime);
    }
    /* Write out the new order and start times */
    fprintf(stderr, "\nSummary of files and start times used:\n\n"
            "          File                Start time       Time step\n"
            "---------------------------------------------------------\n");
    for (gmx::index i = 0; i < files.ssize(); i++)
    {
        switch (cont_type[i])
        {
            case TIME_EXPLICIT:
                fprintf(stderr, "%25s   %10.3f %s   %10.3f %s",
                        files[i].c_str(),
                        output_env_conv_time(oenv, settime[i]), timeUnit.c_str(),
                        output_env_conv_time(oenv, timestep[i]), timeUnit.c_str());
                if (i > 0 &&
                    cont_type[i-1] == TIME_EXPLICIT && settime[i] == settime[i-1])
                {
                    fprintf(stderr, " WARNING: same Start time as previous");
                }
                fprintf(stderr, "\n");
                break;
            case TIME_CONTINUE:
                fprintf(stderr, "%25s        Continue from last file\n", files[i].c_str());
                break;
            case TIME_LAST:
                fprintf(stderr, "%25s        Change by same amount as last file\n",
                        files[i].c_str());
                break;
        }
    }
    fprintf(stderr, "\n");

    settime[files.size()]   = FLT_MAX;
    cont_type[files.size()] = TIME_EXPLICIT;
    readtime[files.size()]  = FLT_MAX;
}
示例#8
0
static void dd_collect_vec_sendrecv(gmx_domdec_t                  *dd,
                                    gmx::ArrayRef<const gmx::RVec> lv,
                                    gmx::ArrayRef<gmx::RVec>       v)
{
    if (!DDMASTER(dd))
    {
#if GMX_MPI
        const int numHomeAtoms = dd->comm->atomRanges.numHomeAtoms();
        MPI_Send(const_cast<void *>(static_cast<const void *>(lv.data())), numHomeAtoms*sizeof(rvec), MPI_BYTE,
                 dd->masterrank, dd->rank, dd->mpi_comm_all);
#endif
    }
    else
    {
        AtomDistribution &ma = *dd->ma;

        /* Copy the master coordinates to the global array */
        const t_block &cgs_gl    = dd->comm->cgs_gl;

        int            rank      = dd->masterrank;
        int            localAtom = 0;
        for (const int &i : ma.domainGroups[rank].atomGroups)
        {
            for (int globalAtom = cgs_gl.index[i]; globalAtom < cgs_gl.index[i + 1]; globalAtom++)
            {
                copy_rvec(lv[localAtom++], v[globalAtom]);
            }
        }

        for (int rank = 0; rank < dd->nnodes; rank++)
        {
            if (rank != dd->rank)
            {
                const auto &domainGroups = ma.domainGroups[rank];

                GMX_RELEASE_ASSERT(v.data() != ma.rvecBuffer.data(), "We need different communication and return buffers");

                /* When we send/recv instead of scatter/gather, we might need
                 * to increase the communication buffer size here.
                 */
                if (static_cast<size_t>(domainGroups.numAtoms) > ma.rvecBuffer.size())
                {
                    ma.rvecBuffer.resize(domainGroups.numAtoms);
                }

#if GMX_MPI
                MPI_Recv(ma.rvecBuffer.data(), domainGroups.numAtoms*sizeof(rvec), MPI_BYTE, rank,
                         rank, dd->mpi_comm_all, MPI_STATUS_IGNORE);
#endif
                int localAtom = 0;
                for (const int &cg : domainGroups.atomGroups)
                {
                    for (int globalAtom = cgs_gl.index[cg]; globalAtom < cgs_gl.index[cg + 1]; globalAtom++)
                    {
                        copy_rvec(ma.rvecBuffer[localAtom++], v[globalAtom]);
                    }
                }
            }
        }
    }
}