git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@26 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
286
src/dump.cpp
Normal file
286
src/dump.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
www.cs.sandia.gov/~sjplimp/lammps.html
|
||||
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
||||
|
||||
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.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "mpi.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include "dump.h"
|
||||
#include "atom.h"
|
||||
#include "update.h"
|
||||
#include "group.h"
|
||||
#include "output.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
Dump::Dump(int narg, char **arg)
|
||||
{
|
||||
MPI_Comm_rank(world,&me);
|
||||
MPI_Comm_size(world,&nprocs);
|
||||
|
||||
int n = strlen(arg[0]) + 1;
|
||||
id = new char[n];
|
||||
strcpy(id,arg[0]);
|
||||
|
||||
igroup = group->find(arg[1]);
|
||||
groupbit = group->bitmask[igroup];
|
||||
|
||||
n = strlen(arg[2]) + 1;
|
||||
style = new char[n];
|
||||
strcpy(style,arg[2]);
|
||||
|
||||
n = strlen(arg[4]) + 1;
|
||||
filename = new char[n];
|
||||
strcpy(filename,arg[4]);
|
||||
|
||||
flush_flag = 1;
|
||||
format = NULL;
|
||||
format_user = NULL;
|
||||
|
||||
maxbuf = 0;
|
||||
buf = NULL;
|
||||
|
||||
// parse filename for special syntax
|
||||
// if contains '%', write one file per proc and replace % with proc-ID
|
||||
// if contains '*', write one file per timestep and replace * with timestep
|
||||
// check file suffixes
|
||||
// if ends in .bin = binary file
|
||||
// else if ends in .gz = gzipped text file
|
||||
// else ASCII text file
|
||||
|
||||
compressed = 0;
|
||||
binary = 0;
|
||||
multifile = 0;
|
||||
multiproc = 0;
|
||||
|
||||
char *ptr;
|
||||
if (ptr = strchr(filename,'%')) {
|
||||
multiproc = 1;
|
||||
char *extend = new char[strlen(filename) + 16];
|
||||
*ptr = '\0';
|
||||
sprintf(extend,"%s%d%s",filename,me,ptr+1);
|
||||
delete [] filename;
|
||||
n = strlen(extend) + 1;
|
||||
filename = new char[n];
|
||||
strcpy(filename,extend);
|
||||
delete [] extend;
|
||||
}
|
||||
|
||||
if (strchr(filename,'*')) multifile = 1;
|
||||
|
||||
char *suffix = filename + strlen(filename) - strlen(".bin");
|
||||
if (suffix > filename && strcmp(suffix,".bin") == 0) binary = 1;
|
||||
suffix = filename + strlen(filename) - strlen(".gz");
|
||||
if (suffix > filename && strcmp(suffix,".gz") == 0) compressed = 1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
Dump::~Dump()
|
||||
{
|
||||
delete [] id;
|
||||
delete [] style;
|
||||
delete [] filename;
|
||||
|
||||
delete [] format;
|
||||
delete [] format_default;
|
||||
delete [] format_user;
|
||||
|
||||
memory->sfree(buf);
|
||||
|
||||
// XTC style sets fp to NULL since it closes file in its destructor
|
||||
|
||||
if (multifile == 0 && fp != NULL) {
|
||||
if (multiproc) fclose(fp);
|
||||
else if (me == 0) fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void Dump::write()
|
||||
{
|
||||
// if file per timestep, open new file
|
||||
|
||||
if (multifile) openfile();
|
||||
|
||||
// nme = # of dump lines this proc will contribute to dump
|
||||
// ntotal = total # of dump lines
|
||||
// nmax = max # of dump lines on any proc
|
||||
|
||||
int nme = count();
|
||||
|
||||
int ntotal,nmax;
|
||||
if (multiproc) nmax = nme;
|
||||
else {
|
||||
MPI_Allreduce(&nme,&ntotal,1,MPI_INT,MPI_SUM,world);
|
||||
MPI_Allreduce(&nme,&nmax,1,MPI_INT,MPI_MAX,world);
|
||||
}
|
||||
|
||||
// write timestep header
|
||||
|
||||
if (multiproc) write_header(nme);
|
||||
else if (me == 0) write_header(ntotal);
|
||||
|
||||
// grow communication buffer if necessary
|
||||
|
||||
if (nmax*size_one > maxbuf) {
|
||||
maxbuf = nmax*size_one;
|
||||
memory->sfree(buf);
|
||||
buf = (double *) memory->smalloc(maxbuf*sizeof(double),"dump:buf");
|
||||
}
|
||||
|
||||
// pack my data into buf
|
||||
// send_size = # of quantities in buf
|
||||
|
||||
int me_size = pack();
|
||||
|
||||
// multiproc = 1 = each proc writes own data to own file
|
||||
// multiproc = 0 = all procs write to one file thru proc 0
|
||||
// proc 0 pings each proc, receives it's data, writes to file
|
||||
// all other procs wait for ping, send their data to proc 0
|
||||
|
||||
if (multiproc) write_data(me_size/size_one,buf);
|
||||
else {
|
||||
int tmp,nlines;
|
||||
MPI_Status status;
|
||||
MPI_Request request;
|
||||
|
||||
if (me == 0) {
|
||||
for (int iproc = 0; iproc < nprocs; iproc++) {
|
||||
if (iproc) {
|
||||
MPI_Irecv(buf,maxbuf,MPI_DOUBLE,iproc,0,world,&request);
|
||||
MPI_Send(&tmp,0,MPI_INT,iproc,0,world);
|
||||
MPI_Wait(&request,&status);
|
||||
MPI_Get_count(&status,MPI_DOUBLE,&nlines);
|
||||
nlines /= size_one;
|
||||
} else nlines = me_size/size_one;
|
||||
|
||||
write_data(nlines,buf);
|
||||
}
|
||||
if (flush_flag) fflush(fp);
|
||||
|
||||
} else {
|
||||
MPI_Recv(&tmp,0,MPI_INT,0,0,world,&status);
|
||||
MPI_Rsend(buf,me_size,MPI_DOUBLE,0,0,world);
|
||||
}
|
||||
}
|
||||
|
||||
// if file per timestep, close file
|
||||
|
||||
if (multifile) {
|
||||
if (multiproc) fclose(fp);
|
||||
else if (me == 0) fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
process params common to all dumps here
|
||||
if unknown param, call modify_param specific to the dump
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Dump::modify_params(int narg, char **arg)
|
||||
{
|
||||
if (narg == 0) error->all("Illegal dump_modify command");
|
||||
|
||||
int iarg = 0;
|
||||
while (iarg < narg) {
|
||||
if (strcmp(arg[iarg],"format") == 0) {
|
||||
if (iarg+2 > narg) error->all("Illegal dump_modify command");
|
||||
delete [] format_user;
|
||||
format_user = NULL;
|
||||
if (strcmp(arg[iarg+1],"none")) {
|
||||
int n = strlen(arg[iarg+1]) + 1;
|
||||
format_user = new char[n];
|
||||
strcpy(format_user,arg[iarg+1]);
|
||||
}
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"flush") == 0) {
|
||||
if (iarg+2 > narg) error->all("Illegal dump_modify command");
|
||||
if (strcmp(arg[iarg+1],"yes") == 0) flush_flag = 1;
|
||||
else if (strcmp(arg[iarg+1],"no") == 0) flush_flag = 0;
|
||||
else error->all("Illegal dump_modify command");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"every") == 0) {
|
||||
if (iarg+2 > narg) error->all("Illegal dump_modify command");
|
||||
int n = atoi(arg[iarg+1]);
|
||||
if (n <= 0) error->all("Illegal dump_modify command");
|
||||
int idump;
|
||||
for (idump = 0; idump < output->ndump; idump++)
|
||||
if (strcmp(id,output->dump[idump]->id) == 0) break;
|
||||
output->dump_every[idump] = n;
|
||||
iarg += 2;
|
||||
} else {
|
||||
int n = modify_param(narg-iarg,&arg[iarg]);
|
||||
if (n == 0) error->all("Illegal dump_modify command");
|
||||
iarg += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return # of bytes of allocated memory in buf
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Dump::memory_usage()
|
||||
{
|
||||
int bytes = maxbuf * sizeof(double);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
generic opening of a dump file
|
||||
ASCII or binary or gzipped
|
||||
some derived classes override this function
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Dump::openfile()
|
||||
{
|
||||
// if one file per timestep, replace '*' with current timestep
|
||||
|
||||
char *filecurrent;
|
||||
if (multifile == 0) filecurrent = filename;
|
||||
else {
|
||||
filecurrent = new char[strlen(filename) + 16];
|
||||
char *ptr = strchr(filename,'*');
|
||||
*ptr = '\0';
|
||||
sprintf(filecurrent,"%s%d%s",filename,update->ntimestep,ptr+1);
|
||||
*ptr = '*';
|
||||
}
|
||||
|
||||
// open one file on proc 0 or file on every proc
|
||||
|
||||
if (me == 0 || multiproc) {
|
||||
if (compressed) {
|
||||
#ifdef GZIP
|
||||
char gzip[128];
|
||||
sprintf(gzip,"gzip -6 > %s",filecurrent);
|
||||
fp = popen(gzip,"w");
|
||||
#else
|
||||
error->one("Cannot open gzipped file");
|
||||
#endif
|
||||
} else if (binary) {
|
||||
fp = fopen(filecurrent,"wb");
|
||||
} else {
|
||||
fp = fopen(filecurrent,"w");
|
||||
}
|
||||
|
||||
if (fp == NULL) error->one("Cannot open dump file");
|
||||
}
|
||||
|
||||
// delete string with timestep replaced
|
||||
|
||||
if (multifile) delete [] filecurrent;
|
||||
}
|
||||
Reference in New Issue
Block a user