From 040ec54ecd583268dc204efd0c2302009286d635 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 27 Jun 2013 22:50:14 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@10121 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/USER-COLVARS/group_ndx.cpp | 174 +++++++++++++++++++++++++++++++++ src/USER-COLVARS/group_ndx.h | 55 +++++++++++ 2 files changed, 229 insertions(+) create mode 100644 src/USER-COLVARS/group_ndx.cpp create mode 100644 src/USER-COLVARS/group_ndx.h diff --git a/src/USER-COLVARS/group_ndx.cpp b/src/USER-COLVARS/group_ndx.cpp new file mode 100644 index 0000000000..de63fc7d97 --- /dev/null +++ b/src/USER-COLVARS/group_ndx.cpp @@ -0,0 +1,174 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include "group_ndx.h" +#include "atom.h" +#include "comm.h" +#include "group.h" +#include "memory.h" +#include "error.h" + +#include +#include + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- + helper function. integer comparison for qsort() + ---------------------------------------------------------------------- */ + +static int cmpint(const void *p1, const void *p2) +{ + const int i1 = * static_cast(p1); + const int i2 = * static_cast(p2); + if (i1 == i2) return 0; + else { + if (i1 < i2) return -1; + else return 1; + } +} + +/* ---------------------------------------------------------------------- + helper function. writes out one group to a gromacs style index file + ---------------------------------------------------------------------- */ + +static void write_group(FILE *fp, int gid, Atom *atom, Group *group, int me, + int np, MPI_Comm world, FILE *screen, FILE *logfile) +{ + char fmt[8]; + int *sendlist, *recvlist; + bigint num = group->count(gid); + int lnum, cols; + + if (me == 0) { + if (screen) fprintf(screen, " writing group %s... ", group->names[gid]); + if (logfile) fprintf(logfile, " writing group %s... ", group->names[gid]); + + // the "all" group in LAMMPS is called "System" in gromacs + if (gid == 0) { + fputs("[ System ]\n", fp); + } else { + fprintf(fp,"[ %s ]\n", group->names[gid]); + } + + // derive format string for index lists + bigint j = atom->natoms; + int i = 0; + while (j > 0) { + ++i; + j /= 10; + } + sprintf(fmt,"%%%dd ", i); + cols = 80 / (i+1); + } + + if (num > 0) { + const int * const mask = atom->mask; + const int * const tag = atom->tag; + const int groupbit = group->bitmask[gid]; + const int nlocal = atom->nlocal; + int i,j; + + sendlist = new int[nlocal]; + recvlist = new int[num]; + lnum = 0; + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) sendlist[lnum++] = tag[i]; + + MPI_Status status; + MPI_Request request; + int nrecv,allrecv; + if (me == 0) { + for (i = 0; i < lnum; i++) + recvlist[i] = sendlist[i]; + + allrecv = lnum; + for (int i=1; i < np; ++i) { + MPI_Irecv(recvlist+allrecv,num-allrecv,MPI_INT,i,0, world,&request); + MPI_Send(&nrecv,0,MPI_INT,i,0,world); + MPI_Wait(&request,&status); + MPI_Get_count(&status,MPI_INT,&nrecv); + allrecv += nrecv; + } + + // sort received list + qsort((void *)recvlist, num, sizeof(int), cmpint); + } else { + MPI_Recv(&nrecv,0,MPI_INT,0,0,world,&status); + MPI_Rsend(sendlist,lnum,MPI_INT,0,0,world); + } + delete [] sendlist; + } + + if (me == 0) { + int i, j; + for(i = 0, j = 0; i < num; ++i) { + fprintf(fp,fmt,recvlist[i]); + ++j; + if (j == cols) { + fputs("\n",fp); + j = 0; + } + } + if (j > 0) fputs("\n",fp); + if (screen) fputs("done\n",screen); + if (logfile) fputs("done\n",logfile); + } + if (num > 0) delete[] recvlist; +} + +/* ---------------------------------------------------------------------- */ + +void Group2Ndx::command(int narg, char **arg) +{ + FILE *fp; + + if (narg < 1) error->all(FLERR,"Illegal group2ndx command"); + + if (atom->tag_enable == 0) + error->all(FLERR,"Must have atom IDs for group2ndx command"); + + if (comm->me == 0) { + fp = fopen(arg[0], "w"); + if (fp == NULL) + error->one(FLERR,"Cannot open index file for writing"); + + if (screen) + fprintf(screen, "Writing groups to index file %s:\n",arg[0]); + if (logfile) + fprintf(logfile,"Writing groups to index file %s:\n",arg[0]); + } + + if (narg == 1) { // write out all groups + for (int i=0; i < group->ngroup; ++i) { + write_group(fp,i,atom,group,comm->me,comm->nprocs,world,screen,logfile); + } + + } else { // write only selected groups + for (int i=1; i < narg; ++i) { + int gid = group->find(arg[i]); + if (gid < 0) error->all(FLERR, "Non-existing group requested"); + write_group(fp,gid,atom,group,comm->me,comm->nprocs,world,screen,logfile); + } + } + + if (comm->me == 0) { + if (screen) fputs("\n",screen); + if (logfile) fputs("\n",logfile); + fclose(fp); + } +} + diff --git a/src/USER-COLVARS/group_ndx.h b/src/USER-COLVARS/group_ndx.h new file mode 100644 index 0000000000..e0104f176f --- /dev/null +++ b/src/USER-COLVARS/group_ndx.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMMAND_CLASS + +CommandStyle(group2ndx,Group2Ndx) + +#else + +#ifndef LMP_GROUP_NDX_H +#define LMP_GROUP_NDX_H + +#include "pointers.h" + +namespace LAMMPS_NS { + +class Group2Ndx : protected Pointers { + public: + Group2Ndx(class LAMMPS *lmp) : Pointers(lmp) {}; + void command(int, char **); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +E: Must have atom IDs for group2ndx command + +There are no atom IDs defined in the system, but they are required +to identify atoms in a gromacs style index file. + +E: Cannot open index file for writing + +Self-explanatory. Check your filename, permissions, and disk space or quota. + +*/