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