Merge branch 'develop' into pedone-potentials
This commit is contained in:
@ -279,9 +279,9 @@ This means the variable can then be evaluated as many times as desired
|
||||
and will return those values. There are two ways to cause the next
|
||||
set of per-atom values from the file to be read: use the
|
||||
:doc:`next <next>` command or the next() function in an atom-style
|
||||
variable, as discussed below. Unlike most variable styles
|
||||
atomfile-style variables are **deleted** during a :doc:`clear <clear>`
|
||||
command.
|
||||
variable, as discussed below. Unlike most variable styles, which
|
||||
remain defined, atomfile-style variables are **deleted** during a
|
||||
:doc:`clear <clear>` command.
|
||||
|
||||
The rules for formatting the file are as follows. Each time a set of
|
||||
per-atom values is read, a non-blank line is searched for in the file.
|
||||
@ -289,23 +289,37 @@ The file is read line by line but only up to 254 characters are used.
|
||||
The rest are ignored. A comment character "#" can be used anywhere
|
||||
on a line and all text following and the "#" character are ignored;
|
||||
text starting with the comment character is stripped. Blank lines
|
||||
are skipped. The first "word" of a non-blank line, delimited by
|
||||
white-space, is read as the count N of per-atom lines to immediately
|
||||
follow. N can be the total number of atoms in the system, or only a
|
||||
subset. The next N lines have the following format
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
ID value
|
||||
|
||||
where ID is an atom ID and value is the per-atom numeric value that
|
||||
will be assigned to that atom. IDs can be listed in any order.
|
||||
are skipped. The first non-blank line is expected to contain a single
|
||||
integer number as the count *N* of per-atom lines to follow. *N* can
|
||||
be the total number of atoms in the system or less, indicating that data
|
||||
for a subset is read. The next N lines must consist of two numbers,
|
||||
the atom-ID of the atom for which a value is set followed by a floating
|
||||
point number with the value. The atom-IDs may be listed in any order.
|
||||
|
||||
.. note::
|
||||
|
||||
Every time a set of per-atom lines is read, the value for all
|
||||
atoms is first set to 0.0. Thus values for atoms whose ID does not
|
||||
appear in the set, will remain 0.0.
|
||||
Every time a set of per-atom lines is read, the value of the atomfile
|
||||
variable for **all** atoms is first initialized to 0.0. Thus values
|
||||
for atoms whose ID do not appear in the set in the file will remain
|
||||
at 0.0.
|
||||
|
||||
Below is a small example for the atomfile variable file format:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
# first set
|
||||
4
|
||||
# atom-ID value
|
||||
3 1
|
||||
4 -4
|
||||
1 0.5
|
||||
2 -0.5
|
||||
|
||||
# second set
|
||||
2
|
||||
|
||||
2 1.0
|
||||
4 -1.0
|
||||
|
||||
----------
|
||||
|
||||
|
||||
@ -369,7 +369,8 @@ void Variable::set(int narg, char **arg)
|
||||
data[nvar][0] = new char[MAXLINE];
|
||||
reader[nvar] = new VarReader(lmp,arg[0],arg[2],SCALARFILE);
|
||||
int flag = reader[nvar]->read_scalar(data[nvar][0]);
|
||||
if (flag) error->all(FLERR,"File variable could not read value");
|
||||
if (flag)
|
||||
error->all(FLERR,"File variable {} could not read value from {}", arg[0], arg[2]);
|
||||
|
||||
// ATOMFILE for numbers
|
||||
// which = 1st value
|
||||
@ -387,7 +388,8 @@ void Variable::set(int narg, char **arg)
|
||||
data[nvar][0] = nullptr;
|
||||
reader[nvar] = new VarReader(lmp,arg[0],arg[2],ATOMFILE);
|
||||
int flag = reader[nvar]->read_peratom();
|
||||
if (flag) error->all(FLERR,"Atomfile variable could not read values");
|
||||
if (flag)
|
||||
error->all(FLERR,"Atomfile variable {} could not read values from {}", arg[0], arg[2]);
|
||||
|
||||
// FORMAT
|
||||
// num = 3, which = 1st value
|
||||
@ -5405,7 +5407,8 @@ VarReader::VarReader(LAMMPS *lmp, char *name, char *file, int flag) :
|
||||
if (me == 0) {
|
||||
fp = fopen(file,"r");
|
||||
if (fp == nullptr)
|
||||
error->one(FLERR,"Cannot open file variable file {}: {}", file, utils::getsyserror());
|
||||
error->one(FLERR,"Cannot open {} variable {} file {}: {}", (style == Variable::ATOMFILE)
|
||||
? "atomfile" : "file", name, file, utils::getsyserror());
|
||||
}
|
||||
|
||||
// if atomfile-style variable, must store per-atom values read from file
|
||||
@ -5463,14 +5466,12 @@ int VarReader::read_scalar(char *str)
|
||||
while (true) {
|
||||
ptr = fgets(str,MAXLINE,fp);
|
||||
if (!ptr) { n=0; break; } // end of file
|
||||
ptr[strcspn(ptr,"#")] = '\0'; // strip comment
|
||||
ptr += strspn(ptr," \t\n\r\f"); // strip leading whitespace
|
||||
ptr[strcspn(ptr," \t\n\r\f")] = '\0'; // strip trailing whitespace
|
||||
n = strlen(ptr) + 1;
|
||||
auto line = utils::trim(utils::trim_comment(str));
|
||||
n = line.size() + 1;
|
||||
if (n == 1) continue; // skip if blank line
|
||||
memcpy(str, line.c_str(), n);
|
||||
break;
|
||||
}
|
||||
if (n > 0) memmove(str,ptr,n); // move trimmed string back
|
||||
}
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
if (n == 0) return 1;
|
||||
@ -5486,9 +5487,9 @@ int VarReader::read_scalar(char *str)
|
||||
|
||||
int VarReader::read_peratom()
|
||||
{
|
||||
int i,m,n,nchunk,eof;
|
||||
int i,m,nchunk,eof;
|
||||
tagint tag;
|
||||
char *ptr,*next;
|
||||
char *ptr;
|
||||
double value;
|
||||
|
||||
// set all per-atom values to 0.0
|
||||
@ -5502,24 +5503,22 @@ int VarReader::read_peratom()
|
||||
// read one string from file, convert to Nlines
|
||||
|
||||
char str[MAXLINE];
|
||||
bigint nlines = 0;
|
||||
if (me == 0) {
|
||||
while (true) {
|
||||
ptr = fgets(str,MAXLINE,fp);
|
||||
if (!ptr) { n=0; break; } // end of file
|
||||
ptr[strcspn(ptr,"#")] = '\0'; // strip comment
|
||||
ptr += strspn(ptr," \t\n\r\f"); // strip leading whitespace
|
||||
ptr[strcspn(ptr," \t\n\r\f")] = '\0'; // strip trailing whitespace
|
||||
n = strlen(ptr) + 1;
|
||||
if (n == 1) continue; // skip if blank line
|
||||
if (!ptr) { nlines = 0; break; } // end of file
|
||||
Tokenizer words(utils::trim(utils::trim_comment(str)));
|
||||
if (words.count() == 0) continue; // skip if blank or comment line
|
||||
if (words.count() != 1)
|
||||
error->one(FLERR, "Expected 1 token but found {} when parsing {}", words.count(), str);
|
||||
nlines = utils::bnumeric(FLERR,words.next(),true,lmp);
|
||||
break;
|
||||
}
|
||||
memmove(str,ptr,n); // move trimmed string back
|
||||
}
|
||||
MPI_Bcast(&nlines,1,MPI_LMP_BIGINT,0,world);
|
||||
if (nlines == 0) return 1;
|
||||
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
if (n == 0) return 1;
|
||||
MPI_Bcast(str,n,MPI_CHAR,0,world);
|
||||
bigint nlines = utils::bnumeric(FLERR,str,false,lmp);
|
||||
tagint map_tag_max = atom->map_tag_max;
|
||||
|
||||
bigint nread = 0;
|
||||
@ -5528,24 +5527,22 @@ int VarReader::read_peratom()
|
||||
eof = utils::read_lines_from_file(fp,nchunk,MAXLINE,buffer,me,world);
|
||||
if (eof) return 1;
|
||||
|
||||
char *buf = buffer;
|
||||
for (i = 0; i < nchunk; i++) {
|
||||
next = strchr(buf,'\n');
|
||||
*next = '\0';
|
||||
for (const auto &line : utils::split_lines(buffer)) {
|
||||
try {
|
||||
ValueTokenizer words(buf);
|
||||
ValueTokenizer words(utils::trim_comment(utils::trim(line)));
|
||||
if (words.count() == 0) continue; // skip comment or empty lines
|
||||
if (words.count() != 2)
|
||||
throw TokenizerException(fmt::format("expected 2 tokens but found {}", words.count()), "");
|
||||
tag = words.next_bigint();
|
||||
value = words.next_double();
|
||||
++nread;
|
||||
} catch (TokenizerException &e) {
|
||||
error->all(FLERR,"Invalid atomfile line '{}': {}",buf,e.what());
|
||||
error->all(FLERR,"Invalid atomfile line '{}': {}", line, e.what());
|
||||
}
|
||||
if ((tag <= 0) || (tag > map_tag_max))
|
||||
error->all(FLERR,"Invalid atom ID {} in variable file", tag);
|
||||
if ((m = atom->map(tag)) >= 0) vstore[m] = value;
|
||||
buf = next + 1;
|
||||
}
|
||||
|
||||
nread += nchunk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -216,7 +216,7 @@ TEST_F(VariableTest, CreateDelete)
|
||||
command("variable one internal 2"););
|
||||
TEST_FAILURE(".*ERROR: Cannot use atomfile-style variable unless an atom map exists.*",
|
||||
command("variable eleven atomfile test_variable.atomfile"););
|
||||
TEST_FAILURE(".*ERROR on proc 0: Cannot open file variable file test_variable.xxx.*",
|
||||
TEST_FAILURE(".*ERROR on proc 0: Cannot open file variable nine1 file test_variable.xxx.*",
|
||||
command("variable nine1 file test_variable.xxx"););
|
||||
TEST_FAILURE(".*ERROR: World variable count doesn't match # of partitions.*",
|
||||
command("variable ten10 world xxx xxx"););
|
||||
@ -293,7 +293,7 @@ TEST_F(VariableTest, AtomicSystem)
|
||||
command("variable one atom x"););
|
||||
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
|
||||
command("variable id vector f_press"););
|
||||
TEST_FAILURE(".*ERROR on proc 0: Cannot open file variable file test_variable.xxx.*",
|
||||
TEST_FAILURE(".*ERROR on proc 0: Cannot open atomfile variable ten1 file test_variable.xxx.*",
|
||||
command("variable ten1 atomfile test_variable.xxx"););
|
||||
TEST_FAILURE(".*ERROR: Variable loop: has a circular dependency.*",
|
||||
variable->compute_equal("v_loop"););
|
||||
|
||||
Reference in New Issue
Block a user