Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F86630749
dump.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Oct 7, 16:15
Size
7 KB
Mime Type
text/x-c
Expires
Wed, Oct 9, 16:15 (1 d, 21 h)
Engine
blob
Format
Raw Data
Handle
21456948
Attached To
rLAMMPS lammps
dump.cpp
View Options
/* ----------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
#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"
using
namespace
LAMMPS_NS
;
/* ---------------------------------------------------------------------- */
Dump
::
Dump
(
LAMMPS
*
lmp
,
int
narg
,
char
**
arg
)
:
Pointers
(
lmp
)
{
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
;
}
Event Timeline
Log In to Comment