modernize parsing in fix tmd, add support for comments and empty lines
This commit is contained in:
@ -29,10 +29,10 @@ Description
|
|||||||
"""""""""""
|
"""""""""""
|
||||||
|
|
||||||
Perform targeted molecular dynamics (TMD) on a group of atoms. A
|
Perform targeted molecular dynamics (TMD) on a group of atoms. A
|
||||||
holonomic constraint is used to force the atoms to move towards (or
|
holonomic constraint is used to force the atoms to move towards (or away
|
||||||
away from) the target configuration. The parameter "rho" is
|
from) the target configuration. The parameter "rho" is monotonically
|
||||||
monotonically decreased (or increased) from its initial value to
|
decreased (or increased) from its initial value to rho_final at the end
|
||||||
rho_final at the end of the run.
|
of the run.
|
||||||
|
|
||||||
Rho has distance units and is a measure of the root-mean-squared
|
Rho has distance units and is a measure of the root-mean-squared
|
||||||
distance (RMSD) between the current configuration of the atoms in the
|
distance (RMSD) between the current configuration of the atoms in the
|
||||||
@ -55,22 +55,25 @@ a .gz suffix). The format of the target file1 is as follows:
|
|||||||
|
|
||||||
The first 3 lines may or may not be needed, depending on the format of
|
The first 3 lines may or may not be needed, depending on the format of
|
||||||
the atoms to follow. If image flags are included with the atoms, the
|
the atoms to follow. If image flags are included with the atoms, the
|
||||||
first 3 lo/hi lines must appear in the file. If image flags are not
|
first 3 lo/hi lines **must** appear in the file. If image flags are not
|
||||||
included, the first 3 lines should not appear. The 3 lines contain the
|
included, the first 3 lines **must not** appear. The 3 lines contain the
|
||||||
simulation box dimensions for the atom coordinates, in the same format
|
simulation box dimensions for the atom coordinates, in the same format
|
||||||
as in a LAMMPS data file (see the :doc:`read_data <read_data>` command).
|
as in a LAMMPS data file (see the :doc:`read_data <read_data>` command).
|
||||||
|
|
||||||
The remaining lines each contain an atom ID and its target x,y,z
|
The remaining lines each contain an atom ID and its target x,y,z
|
||||||
coordinates. The atom lines (all or none of them) can optionally be
|
coordinates. The atom lines (all or none of them) can optionally be
|
||||||
followed by 3 integer values: nx,ny,nz. For periodic dimensions, they
|
followed by 3 integer values: nx,ny,nz.For periodic dimensions, they
|
||||||
specify which image of the box the atom is considered to be in, i.e. a
|
specify which image of the box the atom is considered to be in, i.e. a
|
||||||
value of N (positive or negative) means add N times the box length to
|
value of N (positive or negative) means add N times the box length to
|
||||||
the coordinate to get the true value.
|
the coordinate to get the true value. Those 3 integers either must
|
||||||
|
be given for all atoms or none.
|
||||||
|
|
||||||
The atom lines can be listed in any order, but every atom in the group
|
The atom lines can be listed in any order, but every atom in the group
|
||||||
must be listed in the file. Atoms not in the fix group may also be
|
must be listed in the file. Atoms not in the fix group may also be
|
||||||
listed; they will be ignored.
|
listed; they will be ignored.
|
||||||
|
|
||||||
|
Comments starting with '#' and empty lines may be included as well.
|
||||||
|
|
||||||
TMD statistics are written to file2 every N timesteps, unless N is
|
TMD statistics are written to file2 every N timesteps, unless N is
|
||||||
specified as 0, which means no statistics.
|
specified as 0, which means no statistics.
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "modify.h"
|
#include "modify.h"
|
||||||
#include "respa.h"
|
#include "respa.h"
|
||||||
|
#include "tokenizer.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -268,10 +269,8 @@ void FixTMD::initial_integrate(int /*vflag*/)
|
|||||||
work_lambda += lambda*(rho_target - rho_old);
|
work_lambda += lambda*(rho_target - rho_old);
|
||||||
if (!(update->ntimestep % nfileevery) &&
|
if (!(update->ntimestep % nfileevery) &&
|
||||||
(previous_stat != update->ntimestep)) {
|
(previous_stat != update->ntimestep)) {
|
||||||
fprintf(fp,
|
fmt::print(fp, "{} {} {} {} {} {} {} {}\n", update->ntimestep,rho_target,rho_old,
|
||||||
BIGINT_FORMAT " %g %g %g %g %g %g %g\n",
|
gamma_back,gamma_forward,lambda,work_lambda,work_analytical);
|
||||||
update->ntimestep,rho_target,rho_old,
|
|
||||||
gamma_back,gamma_forward,lambda,work_lambda,work_analytical);
|
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
previous_stat = update->ntimestep;
|
previous_stat = update->ntimestep;
|
||||||
}
|
}
|
||||||
@ -392,7 +391,7 @@ void FixTMD::readfile(char *file)
|
|||||||
|
|
||||||
char *buffer = new char[CHUNK*MAXLINE];
|
char *buffer = new char[CHUNK*MAXLINE];
|
||||||
char *next,*bufptr;
|
char *next,*bufptr;
|
||||||
int i,m,n,nlines,imageflag,ix,iy,iz;
|
int i,m,nlines,imageflag,ix,iy,iz;
|
||||||
tagint itag;
|
tagint itag;
|
||||||
double x,y,z,xprd,yprd,zprd;
|
double x,y,z,xprd,yprd,zprd;
|
||||||
|
|
||||||
@ -422,53 +421,66 @@ void FixTMD::readfile(char *file)
|
|||||||
for (i = 0; i < nlines; i++) {
|
for (i = 0; i < nlines; i++) {
|
||||||
next = strchr(bufptr,'\n');
|
next = strchr(bufptr,'\n');
|
||||||
*next = '\0';
|
*next = '\0';
|
||||||
|
// trim comments and skip empty lines
|
||||||
if (firstline) {
|
char *comment = strchr(bufptr,'#');
|
||||||
if (utils::strmatch(bufptr,"^\\s*\\f+\\s+\\f+\\s+xlo\\s+xhi")) {
|
if (comment) *comment = '\0';
|
||||||
double lo,hi;
|
if (!strlen(bufptr)) {
|
||||||
n = sscanf(bufptr,"%lg %lg",&lo,&hi);
|
bufptr = next + 1;
|
||||||
if (n != 2)
|
continue;
|
||||||
error->all(FLERR,"Incorrect format in TMD target file");
|
|
||||||
xprd = hi - lo;
|
|
||||||
bufptr = next + 1;
|
|
||||||
continue;
|
|
||||||
} else if (utils::strmatch(bufptr,"^\\s*\\f+\\s+\\f+\\s+ylo\\s+yhi")) {
|
|
||||||
double lo,hi;
|
|
||||||
n = sscanf(bufptr,"%lg %lg",&lo,&hi);
|
|
||||||
if (n != 2)
|
|
||||||
error->all(FLERR,"Incorrect format in TMD target file");
|
|
||||||
yprd = hi - lo;
|
|
||||||
bufptr = next + 1;
|
|
||||||
continue;
|
|
||||||
} else if (utils::strmatch(bufptr,"^\\s*\\f+\\s+\\f+\\s+zlo\\s+zhi")) {
|
|
||||||
double lo,hi;
|
|
||||||
n = sscanf(bufptr,"%lg %lg",&lo,&hi);
|
|
||||||
if (n != 2)
|
|
||||||
error->all(FLERR,"Incorrect format in TMD target file");
|
|
||||||
zprd = hi - lo;
|
|
||||||
bufptr = next + 1;
|
|
||||||
continue;
|
|
||||||
} else if (utils::trim_and_count_words(bufptr) == 4) {
|
|
||||||
if (xprd >= 0.0 || yprd >= 0.0 || zprd >= 0.0)
|
|
||||||
error->all(FLERR,"Incorrect format in TMD target file");
|
|
||||||
imageflag = 0;
|
|
||||||
firstline = 0;
|
|
||||||
} else if (utils::trim_and_count_words(bufptr) == 7) {
|
|
||||||
if (xprd < 0.0 || yprd < 0.0 || zprd < 0.0)
|
|
||||||
error->all(FLERR,"Incorrect format in TMD target file");
|
|
||||||
imageflag = 1;
|
|
||||||
firstline = 0;
|
|
||||||
} else error->all(FLERR,"Incorrect format in TMD target file");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imageflag)
|
if (firstline) {
|
||||||
n = 7 - sscanf(bufptr,TAGINT_FORMAT " %lg %lg %lg %d %d %d",
|
try {
|
||||||
&itag,&x,&y,&z,&ix,&iy,&iz);
|
ValueTokenizer values(bufptr);
|
||||||
else
|
|
||||||
n = 4 - sscanf(bufptr,TAGINT_FORMAT " %lg %lg %lg",&itag,&x,&y,&z);
|
|
||||||
|
|
||||||
if (n != 0) {
|
if (utils::strmatch(bufptr,"^\\s*\\f+\\s+\\f+\\s+xlo\\s+xhi")) {
|
||||||
error->all(FLERR,"Incorrectly formatted line in TMD target file");
|
auto lo = values.next_double();
|
||||||
|
auto hi = values.next_double();
|
||||||
|
xprd = hi - lo;
|
||||||
|
bufptr = next + 1;
|
||||||
|
continue;
|
||||||
|
} else if (utils::strmatch(bufptr,"^\\s*\\f+\\s+\\f+\\s+ylo\\s+yhi")) {
|
||||||
|
auto lo = values.next_double();
|
||||||
|
auto hi = values.next_double();
|
||||||
|
yprd = hi - lo;
|
||||||
|
bufptr = next + 1;
|
||||||
|
continue;
|
||||||
|
} else if (utils::strmatch(bufptr,"^\\s*\\f+\\s+\\f+\\s+zlo\\s+zhi")) {
|
||||||
|
auto lo = values.next_double();
|
||||||
|
auto hi = values.next_double();
|
||||||
|
zprd = hi - lo;
|
||||||
|
bufptr = next + 1;
|
||||||
|
continue;
|
||||||
|
} else if (utils::trim_and_count_words(bufptr) == 4) {
|
||||||
|
if (xprd >= 0.0 || yprd >= 0.0 || zprd >= 0.0)
|
||||||
|
throw TokenizerException("must use imageflags when providing box boundaries", bufptr);
|
||||||
|
imageflag = 0;
|
||||||
|
firstline = 0;
|
||||||
|
} else if (utils::trim_and_count_words(bufptr) == 7) {
|
||||||
|
if (xprd < 0.0 || yprd < 0.0 || zprd < 0.0)
|
||||||
|
throw TokenizerException("Invalid box boundaries","");
|
||||||
|
imageflag = 1;
|
||||||
|
firstline = 0;
|
||||||
|
} else throw TokenizerException("unknown data", bufptr);
|
||||||
|
}
|
||||||
|
catch (std::exception &e) {
|
||||||
|
error->all(FLERR,"Incorrect format in TMD target file: {}", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ValueTokenizer values(bufptr);
|
||||||
|
itag = values.next_tagint();
|
||||||
|
x = values.next_double();
|
||||||
|
y = values.next_double();
|
||||||
|
z = values.next_double();
|
||||||
|
if (imageflag) {
|
||||||
|
ix = values.next_int();
|
||||||
|
iy = values.next_int();
|
||||||
|
iz = values.next_int();
|
||||||
|
}
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
error->all(FLERR,"Incorrectly formatted line in TMD target file: {}", e.what());
|
||||||
bufptr = next + 1;
|
bufptr = next + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user