Merge branch 'start_dump_h5md' of git://github.com/pdebuyl/lammps into merge_hdf5_support

This commit is contained in:
Axel Kohlmeyer
2015-08-03 16:44:30 -04:00
11 changed files with 1589 additions and 0 deletions

138
doc/dump_h5md.html Normal file
View File

@ -0,0 +1,138 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dump h5md command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dump ID group-ID h5md N file.h5 args
</PRE>
<UL><LI>ID = user-assigned name for the dump
<LI>group-ID = ID of the group of atoms to be imaged
<LI>h5md = style of dump command (other styles <I>atom</I> or <I>cfg</I> or <I>dcd</I> or <I>xtc</I> or <I>xyz</I> or <I>local</I> or <I>custom</I> are discussed on the <A HREF = "dump.html">dump</A> doc page)
<LI>N = dump every this many timesteps
<LI>file.h5 = name of file to write to
<LI>args = list of data elements to dump, with their dump "subintervals".
At least one element must be given and image may only be present if
position is specified first.
<PRE> position options
image
velocity options
force options
species options
file_from ID: do not open a new file, re-use the already opened file from dump ID
box value = <I>yes</I> or <I>no</I>
create_group value = <I>yes</I> or <I>no</I>
author value = quoted string
</PRE>
<P>For the elements <I>position</I>, <I>velocity</I>, <I>force</I> and <I>species</I>, one may specify
a sub-interval to write the data only every N_element iterations of the dump
(i.e. every N*N_element time steps). This is specified by the option
</P>
<PRE> every N_element
</PRE>
<P>that follows directly the element declaration.
</P>
</UL>
<P><B>Examples:</B>
</P>
<PRE>dump h5md1 all h5md 100 dump_h5md.h5 position image
dump h5md1 all h5md 100 dump_h5md.h5 position velocity every 10
</PRE>
<PRE>dump h5md1 all h5md 100 dump_h5md.h5 velocity author "L. Ammps"
</PRE>
<P><B>Description:</B>
</P>
<P>Dump a snapshot of atom coordinates every N timesteps in the <A HREF = "http://www.hdfgroup.org/HDF5/">HDF5</A>
based <A HREF = "http://nongnu.org/h5md/">H5MD</A> file format <A HREF = "#h5md_cpc">(de Buyl et al.)</A>.
HDF5 files are binary, portable and self-describing.
This dump style will write only one file, on the root node.
</P>
<P>Several dumps may write to the same file, by using file_from and referring to a
previously defined dump.
Several groups may also be stored within the same file by defining several dumps.
A dump that refers (via <I>file_from</I>) to an already open dump ID and that
concerns another particle group must specify <I>create_group yes</I>.
</P>
<P>Each data element is written every N*N_element steps. For <I>image</I>, no
subinterval is needed as it must be present at the same interval as <I>position</I>.
<I>image</I> must be given after <I>position</I> in any case.
The box information (edges in each dimension) is stored at the same interval
than the <I>position</I> element, if present. Else it is stored every N steps.
</P>
<P>IMPORTANT NOTE: Because periodic boundary conditions are enforced only
on timesteps when neighbor lists are rebuilt, the coordinates of an
atom written to a dump file may be slightly outside the simulation
box.
</P>
<P><B>Use from write_dump:</B>
</P>
<P>It is possible to use this dump style with the <A HREF = "write_dump.html">write_dump</A> command.
In this case, the subintervals must not be set at all.
<I>write_dump</I> can be used either alone or in conjunction with <I>file_from</I> so that
fixed-in-time data can be stored in the same file as time-dependent data.
</P>
<P>Typically, the <I>species</I> data is fixed. The following two commands store the
position data every 100 timesteps, with the image data, and store once the
species data in the same file.
</P>
<PRE>dump h5md1 all h5md 100 dump.h5 position image
write_dump all h5md dump.h5 file_from h5md1 species
</PRE>
<HR>
<P><B>Restrictions:</B>
</P>
<UL>
<LI>The number of atoms per snapshot cannot change with the h5md style.
<LI>The position data is stored wrapped (box boundaries not enforced, see note above).
<LI>Only orthogonal domains are currently supported. This is a limitation of the
present package and not of H5MD itself.
</UL>
<P>The <I>h5md</I> dump style is part of the USER-H5MD package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info. It also requires
(i) building the ch5md library provided with LAMMPS (See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.) and
(ii) having the <A HREF = "http://www.hdfgroup.org/HDF5/">HDF5</A> library installed (C bindings are sufficient).
The library ch5md is compiled with the h5cc wrapper provided by the HDF5 library.
</P>
<HR>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dump.html">dump</A>, <A HREF = "dump_modify.html">dump_modify</A>, <A HREF = "undump.html">undump</A>
</P>
<HR>
<A NAME = "h5md_cpc"></A>
<P><B>(de Buyl et al.)</B> de Buyl, Colberg and Hofling, H5MD: A structured, efficient,
and portable file format for molecular data, Comp. Phys. Comm. 185(6),
1546-1553 (2014) - <A HREF = "http://arxiv.org/abs/1308.6382/">[arXiv:1308.6382]</A>.
</P>
</HTML>

121
doc/dump_h5md.txt Normal file
View File

@ -0,0 +1,121 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
dump h5md command :h3
[Syntax:]
dump ID group-ID h5md N file.h5 args :pre
ID = user-assigned name for the dump :ulb,l
group-ID = ID of the group of atoms to be imaged :l
h5md = style of dump command (other styles {atom} or {cfg} or {dcd} or {xtc} or {xyz} or {local} or {custom} are discussed on the "dump"_dump.html doc page) :l
N = dump every this many timesteps :l
file.h5 = name of file to write to :l
args = list of data elements to dump, with their dump "subintervals".
At least one element must be given and image may only be present if
position is specified first. :l
position options
image
velocity options
force options
species options
file_from ID: do not open a new file, re-use the already opened file from dump ID
box value = {yes} or {no}
create_group value = {yes} or {no}
author value = quoted string :pre
For the elements {position}, {velocity}, {force} and {species}, one may specify
a sub-interval to write the data only every N_element iterations of the dump
(i.e. every N*N_element time steps). This is specified by the option
every N_element :pre
that follows directly the element declaration.
:ule
[Examples:]
dump h5md1 all h5md 100 dump_h5md.h5 position image
dump h5md1 all h5md 100 dump_h5md.h5 position velocity every 10 :pre
dump h5md1 all h5md 100 dump_h5md.h5 velocity author "L. Ammps" :pre
[Description:]
Dump a snapshot of atom coordinates every N timesteps in the "HDF5"_HDF5_ws
based "H5MD"_h5md file format "(de Buyl et al.)"_#h5md_cpc.
HDF5 files are binary, portable and self-describing.
This dump style will write only one file, on the root node.
Several dumps may write to the same file, by using file_from and referring to a
previously defined dump.
Several groups may also be stored within the same file by defining several dumps.
A dump that refers (via {file_from}) to an already open dump ID and that
concerns another particle group must specify {create_group yes}.
:link(h5md,http://nongnu.org/h5md/)
Each data element is written every N*N_element steps. For {image}, no
subinterval is needed as it must be present at the same interval as {position}.
{image} must be given after {position} in any case.
The box information (edges in each dimension) is stored at the same interval
than the {position} element, if present. Else it is stored every N steps.
IMPORTANT NOTE: Because periodic boundary conditions are enforced only
on timesteps when neighbor lists are rebuilt, the coordinates of an
atom written to a dump file may be slightly outside the simulation
box.
[Use from write_dump:]
It is possible to use this dump style with the "write_dump"_write_dump.html command.
In this case, the subintervals must not be set at all.
{write_dump} can be used either alone or in conjunction with {file_from} so that
fixed-in-time data can be stored in the same file as time-dependent data.
Typically, the {species} data is fixed. The following two commands store the
position data every 100 timesteps, with the image data, and store once the
species data in the same file.
dump h5md1 all h5md 100 dump.h5 position image
write_dump all h5md dump.h5 file_from h5md1 species :pre
:line
[Restrictions:]
:ulb
The number of atoms per snapshot cannot change with the h5md style. :l
The position data is stored wrapped (box boundaries not enforced, see note above). :l
Only orthogonal domains are currently supported. This is a limitation of the
present package and not of H5MD itself. :l
:ule
The {h5md} dump style is part of the USER-H5MD package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info. It also requires
(i) building the ch5md library provided with LAMMPS (See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.) and
(ii) having the "HDF5"_HDF5_ws library installed (C bindings are sufficient).
The library ch5md is compiled with the h5cc wrapper provided by the HDF5 library.
:link(HDF5_ws,http://www.hdfgroup.org/HDF5/)
:line
[Related commands:]
"dump"_dump.html, "dump_modify"_dump_modify.html, "undump"_undump.html
:line
:link(h5md_cpc)
[(de Buyl et al.)] de Buyl, Colberg and Hofling, H5MD: A structured, efficient,
and portable file format for molecular data, Comp. Phys. Comm. 185(6),
1546-1553 (2014) - "\[arXiv:1308.6382\]"_http://arxiv.org/abs/1308.6382/.

25
lib/ch5md/LICENSE Normal file
View File

@ -0,0 +1,25 @@
Copyright (C) 2013-2014 Pierre de Buyl
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
a. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
b. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
c. Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

32
lib/ch5md/Makefile Normal file
View File

@ -0,0 +1,32 @@
EXTRAMAKE=Makefile.lammps.empty
CC=h5cc
HDF5_PATH=/usr
INC=-I include
AR=ar
ARFLAGS=rc
LIB=libch5md.a
all: lib Makefile.lammps
build:
mkdir -p build
build/ch5md.o: src/ch5md.c | build
$(CC) $(INC) -c $< -o $@
.PHONY: Makefile.lammps
Makefile.lammps:
@echo "# Settings that the LAMMPS build will import when this package library is used" > Makefile.lammps
ifneq "$(HDF5_PATH)" "/usr"
@echo "ch5md_SYSINC = -I${HDF5_PATH}/include" >> Makefile.lammps
@echo "ch5md_SYSLIB = -L${HDF5_PATH}/lib" >> Makefile.lammps
endif
$(LIB): build/ch5md.o
$(AR) $(ARFLAGS) $(LIB) build/ch5md.o
lib: $(LIB) Makefile.lammps
clean:
rm -f build/*.o $(LIB) Makefile.lammps

20
lib/ch5md/README Normal file
View File

@ -0,0 +1,20 @@
ch5md : Read and write H5MD files in C
======================================
Copyright (C) 2013-2014 Pierre de Buyl
ch5md is a set of C routines to manipulate H5MD files. H5MD is a file format
specification based on [HDF5](http://www.hdfgroup.org/HDF5/) for storing
molecular data, whose development is found at <http://nongnu.org/h5md/>.
ch5md is developped by Pierre de Buyl and is released under the 3-clause BSD
license that can be found in the file LICENSE.
To use the h5md dump style in lammps, execute make in this directory then 'make
yes-user-h5md' in the src directory of lammps. Rebuild lammps.
If HDF5 is not in a standard system location, use `make HDF5_PATH=/path/to/hdf5`.
In the case of 2015 and more recent debian and ubuntu systems where concurrent
serial and mpi are possible, use the full platform depedent path, i.e.
`HDF5_PATH=/usr/lib/x86_64-linux-gnu/hdf5/serial`

73
lib/ch5md/include/ch5md.h Normal file
View File

@ -0,0 +1,73 @@
/* This file is part of ch5md
* Copyright (C) 2013-2015 Pierre de Buyl
* All rights reserved.
*
* This software may be modified and distributed under the terms
* of the BSD license. See the LICENSE file for details.
*/
#ifndef CH5MD_H
#define CH5MD_H
#ifdef __cplusplus
extern "C" {
#endif
#include "hdf5.h"
#include <stdbool.h>
#define CH5MD_RANK_ERROR -10
typedef struct h5md_element_struct {
hid_t group;
hid_t step;
hid_t time;
hid_t value;
hid_t datatype;
int is_time;
int current_step;
struct h5md_element_struct *link;
struct h5md_particles_group_struct *particles_group;
} h5md_element;
typedef struct h5md_particles_group_struct {
hid_t group;
h5md_element position;
hid_t box;
h5md_element box_edges;
h5md_element image;
h5md_element velocity;
h5md_element force;
h5md_element mass;
h5md_element species;
h5md_element id;
h5md_element charge;
int local_size_max;
} h5md_particles_group;
typedef struct {
hid_t id;
int version[2];
hid_t particles;
hid_t observables;
hid_t parameters;
} h5md_file;
h5md_file h5md_create_file (const char *filename, const char *author, const char *author_email, const char *creator, const char *creator_version);
int h5md_close_file(h5md_file file);
hid_t h5md_open_file (const char *filename);
h5md_particles_group h5md_create_particles_group(h5md_file file, const char *name);
h5md_element h5md_create_time_data(hid_t loc, const char *name, int rank, int int_dims[], hid_t datatype, h5md_element *link);
int h5md_close_element(h5md_element e);
h5md_element h5md_create_fixed_data_simple(hid_t loc, const char *name, int rank, int int_dims[], hid_t datatype, void *data);
h5md_element h5md_create_fixed_data_scalar(hid_t loc, const char *name, hid_t datatype, void *data);
int h5md_append(h5md_element e, void *data, int step, double time);
int h5md_create_box(h5md_particles_group *group, int dim, char *boundary[], bool is_time, double value[], h5md_element *link);
int h5md_write_string_attribute(hid_t loc, const char *obj_name,
const char *att_name, const char *value);
#ifdef __cplusplus
}
#endif
#endif

444
lib/ch5md/src/ch5md.c Normal file
View File

@ -0,0 +1,444 @@
/* This file is part of ch5md
* Copyright (C) 2013-2015 Pierre de Buyl
* All rights reserved.
*
* This software may be modified and distributed under the terms
* of the BSD license. See the LICENSE file for details.
*/
#include "hdf5.h"
#include "ch5md.h"
#include <string.h>
#include <stdlib.h>
#define MIN_CHUNK 10
#define MAX_CHUNK 256
#define MAX_RANK 5
h5md_file h5md_create_file (const char *filename, const char *author, const char *author_email, const char *creator, const char *creator_version)
{
h5md_file file;
hid_t g, g1;
hid_t a, s, t;
hsize_t dims[1];
herr_t status;
file.version[0] = 1;
file.version[1] = 0;
file.id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
g = H5Gcreate(file.id, "h5md", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
dims[0] = 2;
s = H5Screate_simple(1, dims, NULL);
a = H5Acreate(g, "version", H5T_NATIVE_INT, s, H5P_DEFAULT, H5P_DEFAULT);
status = H5Awrite(a, H5T_NATIVE_INT, file.version);
status = H5Aclose(a);
status = H5Sclose(s);
s = H5Screate(H5S_SCALAR);
g1 = H5Gcreate(g, "author", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
t = H5Tcopy(H5T_C_S1);
status = H5Tset_size(t, strlen(author));
a = H5Acreate(g1, "name", t, s, H5P_DEFAULT, H5P_DEFAULT);
status = H5Awrite(a, t, author);
status = H5Aclose(a);
status = H5Tclose(t);
if (NULL!=author_email) {
t = H5Tcopy(H5T_C_S1);
status = H5Tset_size(t, strlen(author_email));
a = H5Acreate(g1, "author_email", t, s, H5P_DEFAULT, H5P_DEFAULT);
status = H5Awrite(a, t, author_email);
status = H5Aclose(a);
status = H5Tclose(t);
}
status = H5Gclose(g1);
g1 = H5Gcreate(g, "creator", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
t = H5Tcopy(H5T_C_S1);
status = H5Tset_size(t, strlen(creator));
a = H5Acreate(g1, "name", t, s, H5P_DEFAULT, H5P_DEFAULT);
status = H5Awrite(a, t, creator);
status = H5Aclose(a);
status = H5Tclose(t);
t = H5Tcopy(H5T_C_S1);
status = H5Tset_size(t, strlen(creator_version));
a = H5Acreate(g1, "version", t, s, H5P_DEFAULT, H5P_DEFAULT);
status = H5Awrite(a, t, creator_version);
status = H5Aclose(a);
status = H5Tclose(t);
status = H5Gclose(g1);
file.particles = H5Gcreate(file.id, "particles", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
file.observables = H5Gcreate(file.id, "observables", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
file.parameters = H5Gcreate(file.id, "parameters", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
return file;
}
int h5md_close_file(h5md_file file) {
H5Gclose(file.particles);
H5Gclose(file.observables);
H5Gclose(file.parameters);
H5Fclose(file.id);
return 0;
}
hid_t h5md_open_file (const char *filename)
{
hid_t file;
hid_t g;
hid_t a, s;
hsize_t dims[1];
int version[2];
int version_ok;
file = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT);
g = H5Gopen(file, "h5md", H5P_DEFAULT);
version_ok = false;
dims[0] = 2;
a = H5Aopen(g, "version", H5P_DEFAULT);
s = H5Aget_space(a);
if (!(H5Sis_simple(s)>0)) {
printf("H5MD version is not a simple dataspace");
H5Sclose(s);
H5Aclose(a);
H5Gclose(g);
H5Fclose(file);
} else {
if (H5Sget_simple_extent_ndims(s)==1) {
H5Sget_simple_extent_dims(s, dims, NULL);
if (dims[0]==2) {
H5Aread(a, H5T_NATIVE_INT, version);
if ( (version[0]==1) && (version[1]==0) ) {version_ok = true;}
}
}
}
H5Aclose(a);
H5Sclose(s);
H5Gclose(g);
if (!version_ok) H5Fclose(file);
return file;
}
h5md_particles_group h5md_create_particles_group(h5md_file file, const char *name)
{
h5md_particles_group group;
group.group = H5Gcreate(file.particles, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
return group;
}
h5md_element h5md_create_time_data(hid_t loc, const char *name, int rank, int int_dims[], hid_t datatype, h5md_element *link)
{
h5md_element td;
hid_t spc, plist;
hsize_t dims[MAX_RANK], max_dims[MAX_RANK], chunks[MAX_RANK];
herr_t status;
int i;
dims[0] = 0 ;
max_dims[0] = H5S_UNLIMITED ;
for (i=0; i<rank; i++) {
dims[i+1] = int_dims[i];
max_dims[i+1] = int_dims[i];
}
chunks[0] = 1 ;
if (MAX_CHUNK<int_dims[0]/4) {
chunks[1] = MAX_CHUNK;
} else {
chunks[1] = int_dims[0];
}
for (i=1; i<rank; i++) {
chunks[i+1]=int_dims[i];
}
td.group = H5Gcreate(loc, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (NULL==link) {
spc = H5Screate_simple( 1 , dims, max_dims);
plist = H5Pcreate(H5P_DATASET_CREATE);
status = H5Pset_chunk(plist, 1, chunks);
td.time = H5Dcreate(td.group, "time", H5T_NATIVE_DOUBLE, spc, H5P_DEFAULT, plist, H5P_DEFAULT);
td.step = H5Dcreate(td.group, "step", H5T_NATIVE_INT, spc, H5P_DEFAULT, plist, H5P_DEFAULT);
H5Pclose(plist);
H5Sclose(spc);
td.link=NULL;
} else {
td.link = link;
status = H5Lcreate_hard(link->group, "step", td.group, "step", H5P_DEFAULT, H5P_DEFAULT);
status = H5Lcreate_hard(link->group, "time", td.group, "time", H5P_DEFAULT, H5P_DEFAULT);
}
spc = H5Screate_simple( rank+1 , dims, max_dims) ;
plist = H5Pcreate(H5P_DATASET_CREATE);
status = H5Pset_chunk(plist, rank+1, chunks);
td.value = H5Dcreate(td.group, "value", datatype, spc, H5P_DEFAULT, plist, H5P_DEFAULT);
H5Pclose(plist);
status = H5Sclose(spc);
td.datatype = datatype;
td.is_time = true;
return td;
}
int h5md_close_element(h5md_element e)
{
herr_t status;
if (!e.is_time) return 0;
if (e.link==NULL) {
status = H5Dclose(e.step);
status = H5Dclose(e.time);
}
status = H5Dclose(e.value);
status = H5Gclose(e.group);
return 0;
}
h5md_element h5md_create_fixed_data_simple(hid_t loc, const char *name, int rank, int int_dims[], hid_t datatype, void *data)
{
h5md_element fd;
hid_t spc;
hsize_t dims[H5S_MAX_RANK];
herr_t status;
int i;
for (i=0; i<rank; i++) {
dims[i] = int_dims[i];
}
spc = H5Screate_simple(rank, dims, NULL);
fd.value = H5Dcreate(loc, name, datatype, spc, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
status = H5Sclose(spc);
status = H5Dwrite(fd.value, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
status = H5Dclose(fd.value);
fd.is_time = false;
return fd;
}
h5md_element h5md_create_fixed_data_scalar(hid_t loc, const char *name, hid_t datatype, void *data)
{
h5md_element fd;
hid_t spc;
herr_t status;
spc = H5Screate(H5S_SCALAR);
fd.value = H5Dcreate(loc, name, datatype, spc, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
status = H5Sclose(spc);
status = H5Dwrite(fd.value, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
status = H5Dclose(fd.value);
fd.is_time = false;
return fd;
}
int h5md_extend_by_one(hid_t dset, hsize_t *dims) {
hid_t file_space;
int rank;
hsize_t maxdims[H5S_MAX_RANK];
// Get dataset information
file_space = H5Dget_space(dset);
rank = H5Sget_simple_extent_ndims(file_space);
if (rank > H5S_MAX_RANK) {
return CH5MD_RANK_ERROR;
}
H5Sget_simple_extent_dims(file_space, dims, maxdims);
H5Sclose(file_space);
// Extend dimensions by one
dims[0] = dims[0]+1;
H5Dset_extent(dset, dims);
return 0;
}
int h5md_append(h5md_element e, void *data, int step, double time) {
hid_t mem_space, file_space;
int i, rank;
hsize_t dims[H5S_MAX_RANK];
hsize_t start[H5S_MAX_RANK], count[H5S_MAX_RANK];
// If not a time-dependent H5MD element, do nothing
if (!e.is_time) return 0;
if (NULL==e.link) {
h5md_extend_by_one(e.step, dims);
// Define hyperslab selection
start[0] = dims[0]-1;
count[0] = 1;
// Select the hyperslab
file_space = H5Dget_space(e.step);
rank = H5Sget_simple_extent_ndims(file_space);
mem_space = H5Screate_simple(rank-1, dims+1, NULL);
// Define hyperslab selection
start[0] = dims[0]-1;
count[0] = 1;
for (i=1 ; i<rank ; i++) {
start[i] = 0;
count[i] = dims[i];
}
H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, NULL, count, NULL);
H5Dwrite(e.step, H5T_NATIVE_INT, mem_space, file_space, H5P_DEFAULT, (void *)&step);
H5Sclose(file_space);
H5Sclose(mem_space);
h5md_extend_by_one(e.time, dims);
// Define hyperslab selection
start[0] = dims[0]-1;
count[0] = 1;
// Select the hyperslab
file_space = H5Dget_space(e.time);
rank = H5Sget_simple_extent_ndims(file_space);
mem_space = H5Screate_simple(rank-1, dims+1, NULL);
// Define hyperslab selection
start[0] = dims[0]-1;
count[0] = 1;
for (i=1 ; i<rank ; i++) {
start[i] = 0;
count[i] = dims[i];
}
H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, NULL, count, NULL);
H5Dwrite(e.time, H5T_NATIVE_DOUBLE, mem_space, file_space, H5P_DEFAULT, (void *)&time);
H5Sclose(file_space);
H5Sclose(mem_space);
}
h5md_extend_by_one(e.value, dims);
// Select the hyperslab
file_space = H5Dget_space(e.value);
rank = H5Sget_simple_extent_ndims(file_space);
mem_space = H5Screate_simple(rank-1, dims+1, NULL);
// Define hyperslab selection
start[0] = dims[0]-1;
count[0] = 1;
for (i=1 ; i<rank ; i++) {
start[i] = 0;
count[i] = dims[i];
}
H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, NULL, count, NULL);
H5Dwrite(e.value, e.datatype, mem_space, file_space, H5P_DEFAULT, data);
H5Sclose(file_space);
H5Sclose(mem_space);
return 0;
}
int h5md_create_box(h5md_particles_group *group, int dim, char *boundary[], bool is_time, double value[], h5md_element *link)
{
hid_t spc, att, t;
hsize_t dims[1];
int int_dims[1];
herr_t status;
int i;
size_t boundary_length, tmp;
//char *tmp_boundary;
// Create box group
group->box = H5Gcreate(group->group, "box", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
// Create dimension attribute
spc = H5Screate(H5S_SCALAR);
att = H5Acreate(group->box, "dimension", H5T_NATIVE_INT, spc, H5P_DEFAULT, H5P_DEFAULT);
status = H5Awrite(att, H5T_NATIVE_INT, &dim);
status = H5Aclose(att);
status = H5Sclose(spc);
// Compute the size of the string type for boundary
dims[0] = dim;
boundary_length=0;
for (i=0; i<dim; i++) {
tmp = strlen(boundary[i])+1;
if (tmp>boundary_length) {
boundary_length=tmp;
}
}
char *tmp_boundary = malloc(dim*sizeof(char)*boundary_length);
for (i=0; i<dim; i++) {
strcpy((tmp_boundary+i*boundary_length), boundary[i]);
}
// Create boundary attribute
t = H5Tcopy(H5T_C_S1);
status = H5Tset_size(t, boundary_length);
spc = H5Screate_simple(1, dims, NULL);
att = H5Acreate(group->box, "boundary", t, spc, H5P_DEFAULT, H5P_DEFAULT);
status = H5Awrite(att, t, tmp_boundary);
free(tmp_boundary);
status = H5Aclose(att);
status = H5Sclose(spc);
status = H5Tclose(t);
// Create edges
// Check if the box is time-dependent or not
int_dims[0]=dim;
if (is_time) {
group->box_edges = h5md_create_time_data(group->box, "edges", 1, int_dims, H5T_NATIVE_DOUBLE, link);
} else {
if (NULL!=value) {
group->box_edges = h5md_create_fixed_data_simple(group->box, "edges", 1, int_dims, H5T_NATIVE_DOUBLE, value);
}
}
status = H5Gclose(group->box);
return 0;
}
int h5md_write_string_attribute(hid_t loc, const char *obj_name,
const char *att_name, const char *value)
{
hid_t obj;
hid_t s, t, a;
herr_t status;
obj = H5Oopen(loc, obj_name, H5P_DEFAULT);
t = H5Tcopy(H5T_C_S1);
status = H5Tset_size(t, strlen(value));
s = H5Screate(H5S_SCALAR);
a = H5Acreate(obj, att_name, t, s, H5P_DEFAULT, H5P_DEFAULT);
status = H5Awrite(a, t, value);
status = H5Aclose(a);
status = H5Sclose(s);
status = H5Tclose(t);
status = H5Oclose(obj);
return 0;
}

64
src/USER-H5MD/Install.sh Normal file
View File

@ -0,0 +1,64 @@
# Install/unInstall package files in LAMMPS
# mode = 0/1/2 for uninstall/install/update
mode=$1
# arg1 = file, arg2 = file it depends on
action () {
if (test $mode = 0) then
rm -f ../$1
elif (! cmp -s $1 ../$1) then
if (test -z "$2" || test -e ../$2) then
cp $1 ..
if (test $mode = 2) then
echo " updating src/$1"
fi
fi
elif (test -n "$2") then
if (test ! -e ../$2) then
rm -f ../$1
fi
fi
}
for file in *.cpp *.h; do
action $file
done
# edit 2 Makefile.package files to include/exclude package info
if (test $1 = 1) then
if (test -e ../Makefile.package) then
sed -i -e 's/[^ \t]*ch5md[^ \t]* //g' ../Makefile.package
sed -i -e 's|^PKG_INC =[ \t]*|&-I..\/..\/lib\/ch5md\/include |' ../Makefile.package
sed -i -e 's|^PKG_PATH =[ \t]*|&-L..\/..\/lib\/ch5md |' ../Makefile.package
sed -i -e 's|^PKG_LIB =[ \t]*|&-lch5md |' ../Makefile.package
sed -i -e 's|^PKG_LIB =[ \t]*|&-lhdf5 |' ../Makefile.package
sed -i -e 's|^PKG_SYSINC =[ \t]*|&$(ch5md_SYSINC) |' ../Makefile.package
sed -i -e 's|^PKG_SYSLIB =[ \t]*|&$(ch5md_SYSLIB) |' ../Makefile.package
sed -i -e 's|^PKG_SYSPATH =[ \t]*|&$(ch5md_SYSPATH) |' ../Makefile.package
fi
if (test -e ../Makefile.package.settings) then
sed -i -e '/^include.*ch5md.*$/d' ../Makefile.package.settings
# multiline form needed for BSD sed on Macs
sed -i -e '4 i \
include ..\/..\/lib\/ch5md\/Makefile.lammps
' ../Makefile.package.settings
fi
elif (test $1 = 0) then
if (test -e ../Makefile.package) then
sed -i -e 's/[^ \t]*ch5md[^ \t]* //g' ../Makefile.package
sed -i -e 's/[^ \t]*hdf5[^ \t]* //g' ../Makefile.package
fi
if (test -e ../Makefile.package.settings) then
sed -i -e '/^include.*ch5md.*$/d' ../Makefile.package.settings
fi
fi

8
src/USER-H5MD/README Normal file
View File

@ -0,0 +1,8 @@
This package provides the h5md dump style.
See the doc page for dump_h5md. This dump style requires building the bundled
ch5md library and HDF5 (see lib/ch5md/README).
The person who created this package is Pierre de Buyl (KU Leuven), see
http://pdebuyl.be/ for contact information. Contact him directly if you have
questions.

557
src/USER-H5MD/dump_h5md.cpp Normal file
View File

@ -0,0 +1,557 @@
/* ----------------------------------------------------------------------
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: Pierre de Buyl (KU Leuven)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "limits.h"
#include "ch5md.h"
#include "dump_h5md.h"
#include "domain.h"
#include "atom.h"
#include "update.h"
#include "group.h"
#include "output.h"
#include "error.h"
#include "force.h"
#include "memory.h"
#include "version.h"
using namespace LAMMPS_NS;
#define MYMIN(a,b) ((a) < (b) ? (a) : (b))
#define MYMAX(a,b) ((a) > (b) ? (a) : (b))
/** Scan common options for the dump elements
*/
int element_args(int narg, char **arg, int *every)
{
int iarg=0;
while (iarg<narg) {
if (strcmp(arg[iarg], "every")==0) {
if (narg<2) return -1;
*every = atoi(arg[iarg+1]);
iarg+=2;
} else {
break;
}
}
return iarg;
}
/* ---------------------------------------------------------------------- */
DumpH5MD::DumpH5MD(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg)
{
if (narg<6) error->all(FLERR,"Illegal dump h5md command");
if (binary || compressed || multifile || multiproc)
error->all(FLERR,"Invalid dump h5md filename");
if (domain->triclinic!=0)
error->all(FLERR,"Invalid domain for dump h5md. Only triclinic domains supported.");
size_one = 6;
sort_flag = 1;
sortcol = 0;
format_default = NULL;
flush_flag = 0;
unwrap_flag = 0;
datafile_from_dump = -1;
author_name=NULL;
every_dump = force->inumeric(FLERR,arg[3]);
every_position = every_image = -1;
every_velocity = every_force = every_species = -1;
every_charge = -1;
do_box=true;
create_group=true;
bool box_is_set, create_group_is_set;
box_is_set = create_group_is_set = false;
int iarg=5;
int n_parsed, default_every;
size_one=0;
if (every_dump==0) default_every=0; else default_every=1;
while (iarg<narg) {
if (strcmp(arg[iarg], "position")==0) {
every_position=default_every;
iarg+=1;
n_parsed = element_args(narg-iarg, &arg[iarg], &every_position);
if (n_parsed<0) error->all(FLERR, "Illegal dump h5md command");
iarg += n_parsed;
size_one+=domain->dimension;
} else if (strcmp(arg[iarg], "image")==0) {
if (every_position<0) error->all(FLERR, "Illegal dump h5md command");
iarg+=1;
size_one+=domain->dimension;
every_image = every_position;
} else if (strcmp(arg[iarg], "velocity")==0) {
every_velocity = default_every;
iarg+=1;
n_parsed = element_args(narg-iarg, &arg[iarg], &every_velocity);
if (n_parsed<0) error->all(FLERR, "Illegal dump h5md command");
iarg += n_parsed;
size_one+=domain->dimension;
} else if (strcmp(arg[iarg], "force")==0) {
every_force = default_every;
iarg+=1;
n_parsed = element_args(narg-iarg, &arg[iarg], &every_force);
if (n_parsed<0) error->all(FLERR, "Illegal dump h5md command");
iarg += n_parsed;
size_one+=domain->dimension;
} else if (strcmp(arg[iarg], "species")==0) {
every_species=default_every;
iarg+=1;
n_parsed = element_args(narg-iarg, &arg[iarg], &every_species);
if (n_parsed<0) error->all(FLERR, "Illegal dump h5md command");
iarg += n_parsed;
size_one+=1;
} else if (strcmp(arg[iarg], "charge")==0) {
if (!atom->q_flag)
error->all(FLERR, "Requesting non-allocated quantity q in dump_h5md");
every_charge = default_every;
iarg+=1;
n_parsed = element_args(narg-iarg, &arg[iarg], &every_charge);
if (n_parsed<0) error->all(FLERR, "Illegal dump h5md command");
iarg += n_parsed;
size_one+=1;
} else if (strcmp(arg[iarg], "file_from")==0) {
if (iarg+1>=narg) {
error->all(FLERR, "Invalid number of arguments in dump h5md");
}
if (box_is_set||create_group_is_set)
error->all(FLERR, "Cannot set file_from in dump h5md after box or create_group");
int idump;
for (idump = 0; idump < output->ndump; idump++)
if (strcmp(arg[iarg+1],output->dump[idump]->id) == 0) break;
if (idump == output->ndump) error->all(FLERR,"Cound not find dump_modify ID");
datafile_from_dump = idump;
do_box=false;
create_group=false;
iarg+=2;
} else if (strcmp(arg[iarg], "box")==0) {
if (iarg+1>=narg) {
error->all(FLERR, "Invalid number of arguments in dump h5md");
}
box_is_set = true;
if (strcmp(arg[iarg+1], "yes")==0)
do_box=true;
else if (strcmp(arg[iarg+1], "no")==0)
do_box=false;
else
error->all(FLERR, "Illegal dump h5md command");
iarg+=2;
} else if (strcmp(arg[iarg], "create_group")==0) {
if (iarg+1>=narg) {
error->all(FLERR, "Invalid number of arguments in dump h5md");
}
create_group_is_set = true;
if (strcmp(arg[iarg+1], "yes")==0)
create_group=true;
else if (strcmp(arg[iarg+1], "no")==0) {
create_group=false;
}
else
error->all(FLERR, "Illegal dump h5md command");
iarg+=2;
} else if (strcmp(arg[iarg], "author")==0) {
if (iarg+1>=narg) {
error->all(FLERR, "Invalid number of arguments in dump h5md");
}
if (author_name==NULL) {
author_name = new char[strlen(arg[iarg]+1)];
strcpy(author_name, arg[iarg+1]);
} else {
error->all(FLERR, "Illegal dump h5md command: author argument repeated");
}
iarg+=2;
} else {
error->all(FLERR, "Invalid argument to dump h5md");
}
}
// allocate global array for atom coords
bigint n = group->count(igroup);
natoms = static_cast<int> (n);
if (every_position>=0)
memory->create(dump_position,domain->dimension*natoms,"dump:position");
if (every_image>=0)
memory->create(dump_image,domain->dimension*natoms,"dump:image");
if (every_velocity>=0)
memory->create(dump_velocity,domain->dimension*natoms,"dump:velocity");
if (every_force>=0)
memory->create(dump_force,domain->dimension*natoms,"dump:force");
if (every_species>=0)
memory->create(dump_species,natoms,"dump:species");
if (every_charge>=0)
memory->create(dump_charge,natoms,"dump:charge");
openfile();
ntotal = 0;
}
/* ---------------------------------------------------------------------- */
DumpH5MD::~DumpH5MD()
{
if (every_position>=0) {
memory->destroy(dump_position);
if (me==0) {
h5md_close_element(particles_data.position);
if (do_box)
h5md_close_element(particles_data.box_edges);
}
}
if (every_image>=0) {
memory->destroy(dump_image);
if (me==0) h5md_close_element(particles_data.image);
}
if (every_velocity>=0) {
memory->destroy(dump_velocity);
if (me==0) h5md_close_element(particles_data.velocity);
}
if (every_force>=0) {
memory->destroy(dump_force);
if (me==0) h5md_close_element(particles_data.force);
}
if (every_species>=0) {
memory->destroy(dump_species);
if (me==0) h5md_close_element(particles_data.species);
}
if (every_charge>=0) {
memory->destroy(dump_charge);
if (me==0) h5md_close_element(particles_data.charge);
}
}
/* ---------------------------------------------------------------------- */
void DumpH5MD::init_style()
{
if (sort_flag == 0 || sortcol != 0)
error->all(FLERR,"Dump h5md requires sorting by atom ID");
}
/* ---------------------------------------------------------------------- */
void DumpH5MD::openfile()
{
char *group_name;
int group_name_length;
int dims[2];
char *boundary[3];
for (int i=0; i<3; i++) {
boundary[i] = new char[9];
if (domain->periodicity[i]==1) {
strcpy(boundary[i], "periodic");
} else {
strcpy(boundary[i], "none");
}
}
if (me == 0) {
if (datafile_from_dump<0) {
if (author_name==NULL) {
datafile = h5md_create_file(filename, "N/A", NULL, "lammps", LAMMPS_VERSION);
} else {
datafile = h5md_create_file(filename, author_name, NULL, "lammps", LAMMPS_VERSION);
}
group_name_length = strlen(group->names[igroup]);
group_name = new char[group_name_length];
strcpy(group_name, group->names[igroup]);
if (create_group) {
particles_data = h5md_create_particles_group(datafile, group_name);
} else {
particles_data.group = H5Gopen(datafile.particles, group_name, H5P_DEFAULT);
}
delete [] group_name;
dims[0] = natoms;
dims[1] = domain->dimension;
if (every_position>0) {
particles_data.position = h5md_create_time_data(particles_data.group, "position", 2, dims, H5T_NATIVE_DOUBLE, NULL);
h5md_create_box(&particles_data, dims[1], boundary, true, NULL, &particles_data.position);
}
if (every_image>0)
particles_data.image = h5md_create_time_data(particles_data.group, "image", 2, dims, H5T_NATIVE_INT, &particles_data.position);
if (every_velocity>0)
particles_data.velocity = h5md_create_time_data(particles_data.group, "velocity", 2, dims, H5T_NATIVE_DOUBLE, NULL);
if (every_force>0)
particles_data.force = h5md_create_time_data(particles_data.group, "force", 2, dims, H5T_NATIVE_DOUBLE, NULL);
if (every_species>0)
particles_data.species = h5md_create_time_data(particles_data.group, "species", 1, dims, H5T_NATIVE_INT, NULL);
if (every_charge>0) {
particles_data.charge = h5md_create_time_data(particles_data.group, "charge", 1, dims, H5T_NATIVE_DOUBLE, NULL);
h5md_write_string_attribute(particles_data.group, "charge", "type", "effective");
}
} else {
DumpH5MD* other_dump;
other_dump=(DumpH5MD*)output->dump[datafile_from_dump];
datafile = other_dump->datafile;
group_name_length = strlen(group->names[igroup]);
group_name = new char[group_name_length];
strcpy(group_name, group->names[igroup]);
if (create_group) {
particles_data = h5md_create_particles_group(datafile, group_name);
} else {
particles_data = other_dump->particles_data;
}
dims[0] = natoms;
dims[1] = domain->dimension;
if (every_position>0) {
particles_data.position = h5md_create_time_data(particles_data.group, "position", 2, dims, H5T_NATIVE_DOUBLE, NULL);
h5md_create_box(&particles_data, dims[1], boundary, true, NULL, &particles_data.position);
}
if (every_image>0)
particles_data.image = h5md_create_time_data(particles_data.group, "image", 2, dims, H5T_NATIVE_INT, &particles_data.position);
if (every_velocity>0)
particles_data.velocity = h5md_create_time_data(particles_data.group, "velocity", 2, dims, H5T_NATIVE_DOUBLE, NULL);
if (every_force>0)
particles_data.force = h5md_create_time_data(particles_data.group, "force", 2, dims, H5T_NATIVE_DOUBLE, NULL);
if (every_species>0)
particles_data.species = h5md_create_time_data(particles_data.group, "species", 1, dims, H5T_NATIVE_INT, NULL);
if (every_charge>0) {
particles_data.charge = h5md_create_time_data(particles_data.group, "charge", 1, dims, H5T_NATIVE_DOUBLE, NULL);
h5md_write_string_attribute(particles_data.group, "charge", "type", "effective");
}
}
}
if (author_name!=NULL) delete [] author_name;
for (int i=0; i<3; i++) {
delete [] boundary[i];
}
}
/* ---------------------------------------------------------------------- */
void DumpH5MD::write_header(bigint nbig)
{
return;
}
/* ---------------------------------------------------------------------- */
void DumpH5MD::pack(tagint *ids)
{
int m,n;
tagint *tag = atom->tag;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
int *species = atom->type;
double *q = atom->q;
imageint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int dim=domain->dimension;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
m = n = 0;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (every_position>=0) {
int ix = (image[i] & IMGMASK) - IMGMAX;
int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
int iz = (image[i] >> IMG2BITS) - IMGMAX;
if (unwrap_flag == 1) {
buf[m++] = (x[i][0] + ix * xprd);
buf[m++] = (x[i][1] + iy * yprd);
if (dim>2) buf[m++] = (x[i][2] + iz * zprd);
} else {
buf[m++] = x[i][0];
buf[m++] = x[i][1];
if (dim>2) buf[m++] = x[i][2];
}
if (every_image>=0) {
buf[m++] = ix;
buf[m++] = iy;
if (dim>2) buf[m++] = iz;
}
}
if (every_velocity>=0) {
buf[m++] = v[i][0];
buf[m++] = v[i][1];
if (dim>2) buf[m++] = v[i][2];
}
if (every_force>=0) {
buf[m++] = f[i][0];
buf[m++] = f[i][1];
if (dim>2) buf[m++] = f[i][2];
}
if (every_species>=0)
buf[m++] = species[i];
if (every_charge>=0)
buf[m++] = q[i];
ids[n++] = tag[i];
}
}
/* ---------------------------------------------------------------------- */
void DumpH5MD::write_data(int n, double *mybuf)
{
// copy buf atom coords into global array
int m = 0;
int dim = domain->dimension;
int k = dim*ntotal;
int k_image = dim*ntotal;
int k_velocity = dim*ntotal;
int k_force = dim*ntotal;
int k_species = ntotal;
int k_charge = ntotal;
for (int i = 0; i < n; i++) {
if (every_position>=0) {
for (int j=0; j<dim; j++) {
dump_position[k++] = mybuf[m++];
}
if (every_image>=0)
for (int j=0; j<dim; j++) {
dump_image[k_image++] = mybuf[m++];
}
}
if (every_velocity>=0)
for (int j=0; j<dim; j++) {
dump_velocity[k_velocity++] = mybuf[m++];
}
if (every_force>=0)
for (int j=0; j<dim; j++) {
dump_force[k_force++] = mybuf[m++];
}
if (every_species>=0)
dump_species[k_species++] = mybuf[m++];
if (every_charge>=0)
dump_charge[k_charge++] = mybuf[m++];
ntotal++;
}
// if last chunk of atoms in this snapshot, write global arrays to file
if (ntotal == natoms) {
if (every_dump>0) {
write_frame();
ntotal = 0;
} else {
write_fixed_frame();
}
}
}
/* ---------------------------------------------------------------------- */
int DumpH5MD::modify_param(int narg, char **arg)
{
if (strcmp(arg[0],"unwrap") == 0) {
if (narg < 2) error->all(FLERR,"Illegal dump_modify command");
if (strcmp(arg[1],"yes") == 0) unwrap_flag = 1;
else if (strcmp(arg[1],"no") == 0) unwrap_flag = 0;
else error->all(FLERR,"Illegal dump_modify command");
return 2;
}
return 0;
}
/* ---------------------------------------------------------------------- */
void DumpH5MD::write_frame()
{
int local_step;
double local_time;
double edges[3];
local_step = update->ntimestep;
local_time = local_step * update->dt;
edges[0] = boxxhi - boxxlo;
edges[1] = boxyhi - boxylo;
edges[2] = boxzhi - boxzlo;
if (every_position>0) {
if (local_step % (every_position*every_dump) == 0) {
h5md_append(particles_data.position, dump_position, local_step, local_time);
h5md_append(particles_data.box_edges, edges, local_step, local_time);
if (every_image>0)
h5md_append(particles_data.image, dump_image, local_step, local_time);
}
} else {
if (do_box) h5md_append(particles_data.box_edges, edges, local_step, local_time);
}
if (every_velocity>0 && local_step % (every_velocity*every_dump) == 0) {
h5md_append(particles_data.velocity, dump_velocity, local_step, local_time);
}
if (every_force>0 && local_step % (every_force*every_dump) == 0) {
h5md_append(particles_data.force, dump_force, local_step, local_time);
}
if (every_species>0 && local_step % (every_species*every_dump) == 0) {
h5md_append(particles_data.species, dump_species, local_step, local_time);
}
if (every_charge>0 && local_step % (every_charge*every_dump) == 0) {
h5md_append(particles_data.charge, dump_charge, local_step, local_time);
}
}
void DumpH5MD::write_fixed_frame()
{
double edges[3];
int dims[2];
char *boundary[3];
hid_t a, s, t;
herr_t status;
for (int i=0; i<3; i++) {
boundary[i] = new char[9];
if (domain->periodicity[i]==1) {
strcpy(boundary[i], "periodic");
} else {
strcpy(boundary[i], "none");
}
}
dims[0] = natoms;
dims[1] = domain->dimension;
edges[0] = boxxhi - boxxlo;
edges[1] = boxyhi - boxylo;
edges[2] = boxzhi - boxzlo;
if (every_position==0) {
particles_data.position = h5md_create_fixed_data_simple(particles_data.group, "position", 2, dims, H5T_NATIVE_DOUBLE, dump_position);
h5md_create_box(&particles_data, dims[1], boundary, false, edges, NULL);
if (every_image==0)
particles_data.image = h5md_create_fixed_data_simple(particles_data.group, "image", 2, dims, H5T_NATIVE_INT, dump_image);
}
if (every_velocity==0)
particles_data.velocity = h5md_create_fixed_data_simple(particles_data.group, "velocity", 2, dims, H5T_NATIVE_DOUBLE, dump_velocity);
if (every_force==0)
particles_data.force = h5md_create_fixed_data_simple(particles_data.group, "force", 2, dims, H5T_NATIVE_DOUBLE, dump_force);
if (every_species==0)
particles_data.species = h5md_create_fixed_data_simple(particles_data.group, "species", 1, dims, H5T_NATIVE_INT, dump_species);
if (every_charge==0) {
particles_data.charge = h5md_create_fixed_data_simple(particles_data.group, "charge", 1, dims, H5T_NATIVE_INT, dump_charge);
h5md_write_string_attribute(particles_data.group, "charge", "type", "effective");
}
for (int i=0; i<3; i++) {
delete [] boundary[i];
}
}

107
src/USER-H5MD/dump_h5md.h Normal file
View File

@ -0,0 +1,107 @@
/* -*- 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.
Contributing author: Pierre de Buyl (KU Leuven)
------------------------------------------------------------------------- */
#ifdef DUMP_CLASS
DumpStyle(h5md,DumpH5MD)
#else
#ifndef LMP_DUMP_H5MD_H
#define LMP_DUMP_H5MD_H
#include "dump.h"
#include "ch5md.h"
namespace LAMMPS_NS {
class DumpH5MD : public Dump {
public:
DumpH5MD(class LAMMPS *, int, char**);
virtual ~DumpH5MD();
private:
int natoms,ntotal;
int nevery_save;
int unwrap_flag; // 1 if atom coords are unwrapped, 0 if no
h5md_file datafile;
int datafile_from_dump;
h5md_particles_group particles_data;
char *author_name;
bool do_box;
bool create_group;
// data arrays and intervals
int every_dump;
double *dump_position;
int every_position;
int *dump_image;
int every_image;
double *dump_velocity;
int every_velocity;
double *dump_force;
int every_force;
int *dump_species;
int every_species;
int *dump_charge;
int every_charge;
void init_style();
int modify_param(int, char **);
void openfile();
void write_header(bigint);
void pack(tagint *);
void write_data(int, double *);
void write_frame();
void write_fixed_frame();
};
}
#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: Invalid number of arguments in dump h5md
Make sure that each data item (position, etc.) is followed by a dump
interval.
E: Dump h5md requires sorting by atom ID
Use the dump_modify sort command to enable this.
E: Cannot use variable every setting for dump xtc
The format of this file requires snapshots at regular intervals.
E: Cannot change dump_modify every for dump xtc
The frequency of writing dump xtc snapshots cannot be changed.
E: Cannot set file_from in dump h5md after box or create_group
The file_from option modifies the box and create_group options and
they must appear after file_from if used.
*/