Merge remote-tracking branch 'github/develop' into general-triclinic

This commit is contained in:
Axel Kohlmeyer
2024-04-02 09:41:21 -04:00
37 changed files with 457 additions and 373 deletions

View File

@ -139,12 +139,9 @@ if(PKG_KSPACE)
message(WARNING "Using KISS FFT with the CUDA backend of Kokkos may be sub-optimal.") message(WARNING "Using KISS FFT with the CUDA backend of Kokkos may be sub-optimal.")
target_compile_definitions(lammps PRIVATE -DFFT_KOKKOS_KISS) target_compile_definitions(lammps PRIVATE -DFFT_KOKKOS_KISS)
elseif(FFT_KOKKOS STREQUAL "CUFFT") elseif(FFT_KOKKOS STREQUAL "CUFFT")
find_library(CUFFT_LIBRARY cufft) find_package(CUDAToolkit REQUIRED)
if (CUFFT_LIBRARY STREQUAL "CUFFT_LIBRARY-NOTFOUND")
message(FATAL_ERROR "Required cuFFT library not found. Check your environment or set CUFFT_LIBRARY to its location")
endif()
target_compile_definitions(lammps PRIVATE -DFFT_KOKKOS_CUFFT) target_compile_definitions(lammps PRIVATE -DFFT_KOKKOS_CUFFT)
target_link_libraries(lammps PRIVATE ${CUFFT_LIBRARY}) target_link_libraries(lammps PRIVATE CUDA::cufft)
endif() endif()
elseif(Kokkos_ENABLE_HIP) elseif(Kokkos_ENABLE_HIP)
if(NOT ((FFT_KOKKOS STREQUAL "KISS") OR (FFT_KOKKOS STREQUAL "HIPFFT"))) if(NOT ((FFT_KOKKOS STREQUAL "KISS") OR (FFT_KOKKOS STREQUAL "HIPFFT")))

View File

@ -1255,8 +1255,8 @@ Procedures Bound to the :f:type:`lammps` Derived Type
three elements of the global vector calculated by fix recenter into the three elements of the global vector calculated by fix recenter into the
variables *dx*, *dy*, and *dz*, respectively. variables *dx*, *dy*, and *dz*, respectively.
If asked for per-atom or local data, :f:func:`extract_compute` returns a If asked for per-atom or local data, :f:func:`extract_fix` returns a
pointer to actual LAMMPS data. The pointer so returned will have the pointer to actual LAMMPS data. The pointer returned will have the
appropriate size to match the internal data, and will be appropriate size to match the internal data, and will be
type/kind/rank-checked at the time of the assignment. For example, type/kind/rank-checked at the time of the assignment. For example,

View File

@ -31,7 +31,7 @@ Syntax
v_name = per-atom vector calculated by an atom-style variable with name v_name = per-atom vector calculated by an atom-style variable with name
* zero or more keyword/arg pairs may be appended * zero or more keyword/arg pairs may be appended
* keyword = *norm* or *ave* or *bias* or *adof* or *cdof* or *file* or *overwrite* or *format* or *title1* or *title2* or *title3* * keyword = *norm* or *ave* or *bias* or *adof* or *cdof* or *file* or *append* or *overwrite* or *format* or *title1* or *title2* or *title3*
.. parsed-literal:: .. parsed-literal::
@ -51,6 +51,8 @@ Syntax
dof_per_chunk = define this many degrees-of-freedom per chunk for temperature calculation dof_per_chunk = define this many degrees-of-freedom per chunk for temperature calculation
*file* arg = filename *file* arg = filename
filename = file to write results to filename = file to write results to
*append* arg = filename
filename = file to append results to
*overwrite* arg = none = overwrite output file with only latest output *overwrite* arg = none = overwrite output file with only latest output
*format* arg = string *format* arg = string
string = C-style format string string = C-style format string
@ -433,15 +435,21 @@ molecule.
---------- ----------
The *file* keyword allows a filename to be specified. Every .. versionadded:: TBD
:math:`N_\text{freq}` timesteps, a section of chunk info will be written to a new keyword *append*
text file in the following format. A line with the timestep and number of
chunks is written. Then one line per chunk is written, containing the chunk The *file* or *append* keywords allow a filename to be specified. If
ID :math:`(1-N_\text{chunk}),` an optional original ID value, optional *file* is used, then the filename is overwritten if it already exists.
coordinate values for chunks that represent spatial bins, the number of atoms If *append* is used, then the filename is appended to if it already
in the chunk, and one or more calculated values. More explanation of the exists, or created if it does not exist. Every :math:`N_\text{freq}`
optional values is given below. The number of values in each line timesteps, a section of chunk info will be written to a text file in the
corresponds to the number of values specified in the fix ave/chunk following format. A line with the timestep and number of chunks is
written. Then one line per chunk is written, containing the chunk ID
:math:`(1-N_\text{chunk}),` an optional original ID value, optional
coordinate values for chunks that represent spatial bins, the number of
atoms in the chunk, and one or more calculated values. More explanation
of the optional values is given below. The number of values in each
line corresponds to the number of values specified in the fix ave/chunk
command. The number of atoms and the value(s) are summed or average command. The number of atoms and the value(s) are summed or average
quantities, as explained above. quantities, as explained above.

View File

@ -35,7 +35,7 @@ Syntax
v_name[I] = value calculated by a vector-style variable with name, I can include wildcard (see below) v_name[I] = value calculated by a vector-style variable with name, I can include wildcard (see below)
* zero or more keyword/arg pairs may be appended * zero or more keyword/arg pairs may be appended
* keyword = *mode* or *kind* or *file* or *ave* or *start* or *beyond* or *overwrite* or *title1* or *title2* or *title3* * keyword = *mode* or *kind* or *file* or *append* or *ave* or *start* or *beyond* or *overwrite* or *title1* or *title2* or *title3*
.. parsed-literal:: .. parsed-literal::
@ -45,6 +45,8 @@ Syntax
*kind* arg = *global* or *peratom* or *local* *kind* arg = *global* or *peratom* or *local*
*file* arg = filename *file* arg = filename
filename = name of file to output histogram(s) to filename = name of file to output histogram(s) to
*append* arg = filename
filename = name of file to append histogram(s) to
*ave* args = *one* or *running* or *window* *ave* args = *one* or *running* or *window*
one = output a new average value every Nfreq steps one = output a new average value every Nfreq steps
running = output cumulative average of all previous Nfreq steps running = output cumulative average of all previous Nfreq steps
@ -317,19 +319,25 @@ on. The default is step 0. Often input values can be 0.0 at time 0,
so setting *start* to a larger value can avoid including a 0.0 in so setting *start* to a larger value can avoid including a 0.0 in
a running or windowed histogram. a running or windowed histogram.
The *file* keyword allows a filename to be specified. Every *Nfreq* .. versionadded:: TBD
steps, one histogram is written to the file. This includes a leading new keyword *append*
line that contains the timestep, number of bins, the total count of
values contributing to the histogram, the count of values that were The *file* or *append* keywords allow a filename to be specified. If
not histogrammed (see the *beyond* keyword), the minimum value *file* is used, then the filename is overwritten if it already exists.
encountered, and the maximum value encountered. The min/max values If *append* is used, then the filename is appended to if it already
include values that were not histogrammed. Following the leading exists, or created if it does not exist. Every *Nfreq* steps, one
line, one line per bin is written into the file. Each line contains histogram is written to the file. This includes a leading line that
the bin #, the coordinate for the center of the bin (between *lo* and contains the timestep, number of bins, the total count of values
*hi*\ ), the count of values in the bin, and the normalized count. The contributing to the histogram, the count of values that were not
normalized count is the bin count divided by the total count (not histogrammed (see the *beyond* keyword), the minimum value encountered,
including values not histogrammed), so that the normalized values sum and the maximum value encountered. The min/max values include values
to 1.0 across all bins. that were not histogrammed. Following the leading line, one line per
bin is written into the file. Each line contains the bin #, the
coordinate for the center of the bin (between *lo* and *hi*\ ), the
count of values in the bin, and the normalized count. The normalized
count is the bin count divided by the total count (not including values
not histogrammed), so that the normalized values sum to 1.0 across all
bins.
The *overwrite* keyword will continuously overwrite the output file The *overwrite* keyword will continuously overwrite the output file
with the latest output, so that it only contains one timestep worth of with the latest output, so that it only contains one timestep worth of

View File

@ -28,7 +28,7 @@ Syntax
v_name[I] = value calculated by a vector-style variable with name, I can include wildcard (see below) v_name[I] = value calculated by a vector-style variable with name, I can include wildcard (see below)
* zero or more keyword/arg pairs may be appended * zero or more keyword/arg pairs may be appended
* keyword = *mode* or *file* or *ave* or *start* or *off* or *overwrite* or *format* or *title1* or *title2* or *title3* * keyword = *mode* or *file* or *append* or *ave* or *start* or *off* or *overwrite* or *format* or *title1* or *title2* or *title3*
.. parsed-literal:: .. parsed-literal::
@ -45,6 +45,8 @@ Syntax
M = value # from 1 to Nvalues M = value # from 1 to Nvalues
*file* arg = filename *file* arg = filename
filename = name of file to output time averages to filename = name of file to output time averages to
*append* arg = filename
filename = name of file to append time averages to
*overwrite* arg = none = overwrite output file with only latest output *overwrite* arg = none = overwrite output file with only latest output
*format* arg = string *format* arg = string
string = C-style format string string = C-style format string
@ -270,16 +272,21 @@ are effectively constant or are simply current values (e.g., they are
being written to a file with other time-averaged values for purposes being written to a file with other time-averaged values for purposes
of creating well-formatted output). of creating well-formatted output).
The *file* keyword allows a filename to be specified. Every *Nfreq* .. versionadded:: TBD
steps, one quantity or vector of quantities is written to the file for new keyword *append*
each input value specified in the fix ave/time command. For *mode* =
scalar, this means a single line is written each time output is The *file* or *append* keywords allow a filename to be specified. If
performed. Thus the file ends up to be a series of lines, i.e. one *file* is used, then the filename is overwritten if it already exists.
column of numbers for each input value. For *mode* = vector, an array If *append* is used, then the filename is appended to if it already
of numbers is written each time output is performed. The number of rows exists, or created if it does not exist. Every *Nfreq* steps, one
is the length of the input vectors, and the number of columns is the quantity or vector of quantities is written to the file for each input
number of values. Thus the file ends up to be a series of these array value specified in the fix ave/time command. For *mode* = scalar, this
sections. means a single line is written each time output is performed. Thus the
file ends up to be a series of lines, i.e. one column of numbers for
each input value. For *mode* = vector, an array of numbers is written
each time output is performed. The number of rows is the length of the
input vectors, and the number of columns is the number of values. Thus
the file ends up to be a series of these array sections.
.. versionadded:: 4May2022 .. versionadded:: 4May2022

View File

@ -255,23 +255,24 @@ and the fix will issue an error in that case.
.. versionadded:: TBD .. versionadded:: TBD
The keyword *qtotal* causes *fix electrode/conp* and *fix electrode/thermo* The keyword *qtotal* causes *fix electrode/conp* and *fix
to add an overall potential to all electrodes so that the total charge on electrode/thermo* to add an overall potential to all electrodes so that
the electrodes is a specified amount (which may be an equal-style variable). the total charge on the electrodes is a specified amount (which may be
For example, if a user wanted to simulate a solution of excess cations an equal-style variable). For example, if a user wanted to simulate a
such that the total electrolyte charge is +2, setting *qtotal -2* would cause solution of excess cations such that the total electrolyte charge is +2,
the total electrode charge to be -2, so that the simulation box remains overall setting *qtotal -2* would cause the total electrode charge to be -2, so
electroneutral. Since *fix electrode/conq* constrains the total charges of that the simulation box remains overall electroneutral. Since *fix
individual electrodes, and since *symm on* constrains the total charge of all electrode/conq* constrains the total charges of individual electrodes,
electrodes to be zero, either option is incompatible with the *qtotal* keyword and since *symm on* constrains the total charge of all electrodes to be
(even if *qtotal* is set to zero). zero, either option is incompatible with the *qtotal* keyword (even if
*qtotal* is set to zero).
.. versionadded:: TBD .. versionadded:: TBD
The keyword *eta* takes the name of a custom double vector defined via fix The keyword *eta* takes the name of a custom double vector defined via
property/atom. The values will be used instead of the standard eta value. The fix property/atom. The values will be used instead of the standard eta
property/atom fix must be for vector of double values and use the *ghost on* value. The property/atom fix must be for vector of double values and
option. use the *ghost on* option.
Restart, fix_modify, output, run start/stop, minimize info Restart, fix_modify, output, run start/stop, minimize info
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""

View File

@ -159,17 +159,17 @@ surface-to-volume ratio of each processor's subdomain.
for most MPI implementations, but some MPIs provide options for this for most MPI implementations, but some MPIs provide options for this
ordering, e.g. via environment variable settings. ordering, e.g. via environment variable settings.
The *numa* style operates similar to the *twolevel* keyword except The *numa* style operates similar to the *twolevel* keyword except that
that it auto-detects which cores are running on which nodes. it auto-detects which cores are running on which nodes. It will also
It will also subdivide the cores into numa domains. Currently, the subdivide the cores into numa domains. Currently, the number of numa
number of numa domains is not autodetected and must be specified using domains is not auto-detected and must be specified using the
the *numa_nodes* keyword; otherwise, the default value is used. The *numa_nodes* keyword; otherwise, the default value is used. The *numa*
*numa* style uses a different algorithm than the *twolevel* keyword for style uses a different algorithm than the *twolevel* keyword for doing
doing the two-level factorization of the simulation box into a 3d the two-level factorization of the simulation box into a 3d processor
processor grid to minimize off-node communication and communication grid to minimize off-node communication and communication across numa
across numa domains. It does its own MPI-based mapping of nodes and domains. It does its own MPI-based mapping of nodes and cores to the
cores to the regular 3d grid. Thus it may produce a different layout regular 3d grid. Thus it may produce a different layout of the
of the processors than the *twolevel* options. processors than the *twolevel* options.
The *numa* style will give an error if the number of MPI processes is The *numa* style will give an error if the number of MPI processes is
not divisible by the number of cores used per node, or any of the Px not divisible by the number of cores used per node, or any of the Px
@ -182,7 +182,7 @@ or Py or Pz values is greater than 1.
is because it auto-detects which processes are running on which nodes. is because it auto-detects which processes are running on which nodes.
However, it assumes that the lowest ranks are in the first numa However, it assumes that the lowest ranks are in the first numa
domain, and so forth. MPI rank orderings that do not preserve this domain, and so forth. MPI rank orderings that do not preserve this
property might result in more intranode communication between CPUs. property might result in more intra-node communication between CPUs.
The *custom* style uses the file *infile* to define both the 3d The *custom* style uses the file *infile* to define both the 3d
factorization and the mapping of processors to the grid. factorization and the mapping of processors to the grid.
@ -213,7 +213,7 @@ any order, but no processor ID should appear more than once.
---------- ----------
The *numa_nodes* keyword is used to specifiy the number of numa domains The *numa_nodes* keyword is used to specify the number of numa domains
per node. It is currently only used by the *numa* style for two-level per node. It is currently only used by the *numa* style for two-level
factorization to reduce the amount of MPI communications between CPUs. factorization to reduce the amount of MPI communications between CPUs.
A good setting for this will typically be equal to the number of CPU A good setting for this will typically be equal to the number of CPU

View File

@ -960,6 +960,7 @@ elastance
Electroneg Electroneg
electronegative electronegative
electronegativity electronegativity
electroneutral
electroneutrality electroneutrality
Eleftheriou Eleftheriou
ElementN ElementN

View File

@ -3687,7 +3687,7 @@ CONTAINS
n = LEN_TRIM(f_string) n = LEN_TRIM(f_string)
ptr = lammps_malloc(n+1) ptr = lammps_malloc(n+1)
CALL C_F_POINTER(ptr, c_string, [1]) CALL C_F_POINTER(ptr, c_string, [n+1])
DO i=1, n DO i=1, n
c_string(i) = f_string(i:i) c_string(i) = f_string(i:i)
END DO END DO

View File

@ -29,23 +29,23 @@ _texture_2d( vel_tex,int4);
#if (SHUFFLE_AVAIL == 0) #if (SHUFFLE_AVAIL == 0)
#define store_dE(dEacc, ii, inum, tid, t_per_atom, offset, dE) \ #define store_dE(dEacc, ii, inum, tid, t_per_atom, offset, i, dE) \
if (t_per_atom>1) { \ if (t_per_atom>1) { \
simdsync(); \ simdsync(); \
simd_reduce_add1(t_per_atom, red_acc, offset, tid, dEacc); \ simd_reduce_add1(t_per_atom, red_acc, offset, tid, dEacc); \
} \ } \
if (offset==0 && ii<inum) { \ if (offset==0 && ii<inum) { \
dE[ii]=dEacc; \ dE[i]=dEacc; \
} }
#else #else
#define store_drhoE(dEacc, ii, inum, tid, t_per_atom, offset, dE) \ #define store_drhoE(dEacc, ii, inum, tid, t_per_atom, offset, i, dE) \
if (t_per_atom>1) { \ if (t_per_atom>1) { \
for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \ for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \
dEacc += shfl_down(dEacc, s, t_per_atom); \ dEacc += shfl_down(dEacc, s, t_per_atom); \
} \ } \
} \ } \
if (offset==0 && ii<inum) { \ if (offset==0 && ii<inum) { \
dE[ii]=dEacc; \ dE[i]=dEacc; \
} }
#endif #endif
@ -66,7 +66,7 @@ __kernel void k_sph_heatconduction(const __global numtyp4 *restrict x_,
const int inum, const int nbor_pitch, const int inum, const int nbor_pitch,
const __global numtyp4 *restrict v_, const __global numtyp4 *restrict v_,
const int dimension, const int t_per_atom) { const int dimension, const int t_per_atom) {
int tid, ii, offset; int tid, ii, offset, i;
atom_info(t_per_atom,ii,tid,offset); atom_info(t_per_atom,ii,tid,offset);
int n_stride; int n_stride;
@ -77,7 +77,7 @@ __kernel void k_sph_heatconduction(const __global numtyp4 *restrict x_,
acctyp dEacc = (acctyp)0; acctyp dEacc = (acctyp)0;
if (ii<inum) { if (ii<inum) {
int i, numj, nbor, nbor_end; int numj, nbor, nbor_end;
nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj, nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
n_stride,nbor_end,nbor); n_stride,nbor_end,nbor);
@ -140,7 +140,7 @@ __kernel void k_sph_heatconduction(const __global numtyp4 *restrict x_,
} // for nbor } // for nbor
} // if ii } // if ii
store_drhoE(dEacc,ii,inum,tid,t_per_atom,offset,dE); store_drhoE(dEacc,ii,inum,tid,t_per_atom,offset,i,dE);
} }
__kernel void k_sph_heatconduction_fast(const __global numtyp4 *restrict x_, __kernel void k_sph_heatconduction_fast(const __global numtyp4 *restrict x_,
@ -157,7 +157,7 @@ __kernel void k_sph_heatconduction_fast(const __global numtyp4 *restrict x_,
const int inum, const int nbor_pitch, const int inum, const int nbor_pitch,
const __global numtyp4 *restrict v_, const __global numtyp4 *restrict v_,
const int dimension, const int t_per_atom) { const int dimension, const int t_per_atom) {
int tid, ii, offset; int tid, ii, offset, i;
atom_info(t_per_atom,ii,tid,offset); atom_info(t_per_atom,ii,tid,offset);
#ifndef ONETYPE #ifndef ONETYPE
@ -180,7 +180,7 @@ __kernel void k_sph_heatconduction_fast(const __global numtyp4 *restrict x_,
acctyp dEacc = (acctyp)0; acctyp dEacc = (acctyp)0;
if (ii<inum) { if (ii<inum) {
int i, numj, nbor, nbor_end; int numj, nbor, nbor_end;
nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj, nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
n_stride,nbor_end,nbor); n_stride,nbor_end,nbor);
@ -204,7 +204,7 @@ __kernel void k_sph_heatconduction_fast(const __global numtyp4 *restrict x_,
#endif #endif
numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j]; numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j];
int jtype = jx.w; int jtype=jx.w;
#ifndef ONETYPE #ifndef ONETYPE
int mtype=itype+jx.w; int mtype=itype+jx.w;
const numtyp cutsq_p=coeff[mtype].z; const numtyp cutsq_p=coeff[mtype].z;
@ -252,6 +252,6 @@ __kernel void k_sph_heatconduction_fast(const __global numtyp4 *restrict x_,
} // for nbor } // for nbor
} // if ii } // if ii
store_drhoE(dEacc,ii,inum,tid,t_per_atom,offset,dE); store_drhoE(dEacc,ii,inum,tid,t_per_atom,offset,i,dE);
} }

View File

@ -29,17 +29,18 @@ _texture_2d( vel_tex,int4);
#if (SHUFFLE_AVAIL == 0) #if (SHUFFLE_AVAIL == 0)
#define store_drhoE(drhoEacc, ii, inum, tid, t_per_atom, offset, drhoE) \ #define store_drhoE(drhoEacc, ii, inum, tid, t_per_atom, offset, i, drhoE) \
if (t_per_atom>1) { \ if (t_per_atom>1) { \
simdsync(); \ simdsync(); \
simd_reduce_add2(t_per_atom, red_acc, offset, tid, \ simd_reduce_add2(t_per_atom, red_acc, offset, tid, \
drhoEacc.x, drhoEacc.y); \ drhoEacc.x, drhoEacc.y); \
} \ } \
if (offset==0 && ii<inum) { \ if (offset==0 && ii<inum) { \
drhoE[ii]=drhoEacc; \ drhoE[i]=drhoEacc.x; \
drhoE[i+inum]=drhoEacc.y; \
} }
#else #else
#define store_drhoE(drhoEacc, ii, inum, tid, t_per_atom, offset, drhoE) \ #define store_drhoE(drhoEacc, ii, inum, tid, t_per_atom, offset, i, drhoE) \
if (t_per_atom>1) { \ if (t_per_atom>1) { \
for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \ for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \
drhoEacc.x += shfl_down(drhoEacc.x, s, t_per_atom); \ drhoEacc.x += shfl_down(drhoEacc.x, s, t_per_atom); \
@ -47,7 +48,8 @@ _texture_2d( vel_tex,int4);
} \ } \
} \ } \
if (offset==0 && ii<inum) { \ if (offset==0 && ii<inum) { \
drhoE[ii]=drhoEacc; \ drhoE[i]=drhoEacc.x; \
drhoE[i+inum]=drhoEacc.y; \
} }
#endif #endif
@ -105,12 +107,12 @@ __kernel void k_sph_lj(const __global numtyp4 *restrict x_,
const __global int * dev_packed, const __global int * dev_packed,
__global acctyp3 *restrict ans, __global acctyp3 *restrict ans,
__global acctyp *restrict engv, __global acctyp *restrict engv,
__global acctyp2 *restrict drhoE, __global acctyp *restrict drhoE,
const int eflag, const int vflag, const int eflag, const int vflag,
const int inum, const int nbor_pitch, const int inum, const int nbor_pitch,
const __global numtyp4 *restrict v_, const __global numtyp4 *restrict v_,
const int dimension, const int t_per_atom) { const int dimension, const int t_per_atom) {
int tid, ii, offset; int tid, ii, offset, i;
atom_info(t_per_atom,ii,tid,offset); atom_info(t_per_atom,ii,tid,offset);
int n_stride; int n_stride;
@ -124,10 +126,10 @@ __kernel void k_sph_lj(const __global numtyp4 *restrict x_,
for (int i=0; i<6; i++) virial[i]=(acctyp)0; for (int i=0; i<6; i++) virial[i]=(acctyp)0;
} }
acctyp2 drhoEacc; acctyp2 drhoEacc;
drhoEacc.x = drhoEacc.x = (acctyp)0; drhoEacc.x = drhoEacc.y = (acctyp)0;
if (ii<inum) { if (ii<inum) {
int i, numj, nbor, nbor_end; int numj, nbor, nbor_end;
nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj, nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
n_stride,nbor_end,nbor); n_stride,nbor_end,nbor);
@ -246,7 +248,7 @@ __kernel void k_sph_lj(const __global numtyp4 *restrict x_,
} // if ii } // if ii
store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag,
ans,engv); ans,engv);
store_drhoE(drhoEacc,ii,inum,tid,t_per_atom,offset,drhoE); store_drhoE(drhoEacc,ii,inum,tid,t_per_atom,offset,i,drhoE);
} }
__kernel void k_sph_lj_fast(const __global numtyp4 *restrict x_, __kernel void k_sph_lj_fast(const __global numtyp4 *restrict x_,
@ -258,12 +260,12 @@ __kernel void k_sph_lj_fast(const __global numtyp4 *restrict x_,
const __global int * dev_packed, const __global int * dev_packed,
__global acctyp3 *restrict ans, __global acctyp3 *restrict ans,
__global acctyp *restrict engv, __global acctyp *restrict engv,
__global acctyp2 *restrict drhoE, __global acctyp *restrict drhoE,
const int eflag, const int vflag, const int eflag, const int vflag,
const int inum, const int nbor_pitch, const int inum, const int nbor_pitch,
const __global numtyp4 *restrict v_, const __global numtyp4 *restrict v_,
const int dimension, const int t_per_atom) { const int dimension, const int t_per_atom) {
int tid, ii, offset; int tid, ii, offset, i;
atom_info(t_per_atom,ii,tid,offset); atom_info(t_per_atom,ii,tid,offset);
#ifndef ONETYPE #ifndef ONETYPE
@ -289,10 +291,10 @@ __kernel void k_sph_lj_fast(const __global numtyp4 *restrict x_,
for (int i=0; i<6; i++) virial[i]=(acctyp)0; for (int i=0; i<6; i++) virial[i]=(acctyp)0;
} }
acctyp2 drhoEacc; acctyp2 drhoEacc;
drhoEacc.x = drhoEacc.x = (acctyp)0; drhoEacc.x = drhoEacc.y = (acctyp)0;
if (ii<inum) { if (ii<inum) {
int i, numj, nbor, nbor_end; int numj, nbor, nbor_end;
nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj, nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
n_stride,nbor_end,nbor); n_stride,nbor_end,nbor);
@ -325,7 +327,7 @@ __kernel void k_sph_lj_fast(const __global numtyp4 *restrict x_,
#endif #endif
numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j]; numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j];
int jtype = jx.w; int jtype=jx.w;
#ifndef ONETYPE #ifndef ONETYPE
int mtype=itype+jx.w; int mtype=itype+jx.w;
const numtyp cutsq_p=coeff[mtype].z; // cutsq[itype][jtype]; const numtyp cutsq_p=coeff[mtype].z; // cutsq[itype][jtype];
@ -415,12 +417,11 @@ __kernel void k_sph_lj_fast(const __global numtyp4 *restrict x_,
virial[4] += delx*delz*force; virial[4] += delx*delz*force;
virial[5] += dely*delz*force; virial[5] += dely*delz*force;
} }
} }
} // for nbor } // for nbor
} // if ii } // if ii
store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, ans,engv); store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, ans,engv);
store_drhoE(drhoEacc,ii,inum,tid,t_per_atom,offset,drhoE); store_drhoE(drhoEacc,ii,inum,tid,t_per_atom,offset,i,drhoE);
} }

View File

@ -29,17 +29,18 @@ _texture_2d( vel_tex,int4);
#if (SHUFFLE_AVAIL == 0) #if (SHUFFLE_AVAIL == 0)
#define store_drhoE(drhoEacc, ii, inum, tid, t_per_atom, offset, drhoE) \ #define store_drhoE(drhoEacc, ii, inum, tid, t_per_atom, offset, i, drhoE) \
if (t_per_atom>1) { \ if (t_per_atom>1) { \
simdsync(); \ simdsync(); \
simd_reduce_add2(t_per_atom, red_acc, offset, tid, \ simd_reduce_add2(t_per_atom, red_acc, offset, tid, \
drhoEacc.x, drhoEacc.y); \ drhoEacc.x, drhoEacc.y); \
} \ } \
if (offset==0 && ii<inum) { \ if (offset==0 && ii<inum) { \
drhoE[ii]=drhoEacc; \ drhoE[i]=drhoEacc.x; \
drhoE[i+inum]=drhoEacc.y; \
} }
#else #else
#define store_drhoE(drhoEacc, ii, inum, tid, t_per_atom, offset, drhoE) \ #define store_drhoE(drhoEacc, ii, inum, tid, t_per_atom, offset, i, drhoE) \
if (t_per_atom>1) { \ if (t_per_atom>1) { \
for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \ for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \
drhoEacc.x += shfl_down(drhoEacc.x, s, t_per_atom); \ drhoEacc.x += shfl_down(drhoEacc.x, s, t_per_atom); \
@ -47,7 +48,8 @@ _texture_2d( vel_tex,int4);
} \ } \
} \ } \
if (offset==0 && ii<inum) { \ if (offset==0 && ii<inum) { \
drhoE[ii]=drhoEacc; \ drhoE[i]=drhoEacc.x; \
drhoE[i+inum]=drhoEacc.y; \
} }
#endif #endif
@ -61,12 +63,12 @@ __kernel void k_sph_taitwater(const __global numtyp4 *restrict x_,
const __global int * dev_packed, const __global int * dev_packed,
__global acctyp3 *restrict ans, __global acctyp3 *restrict ans,
__global acctyp *restrict engv, __global acctyp *restrict engv,
__global acctyp2 *restrict drhoE, __global acctyp *restrict drhoE,
const int eflag, const int vflag, const int eflag, const int vflag,
const int inum, const int nbor_pitch, const int inum, const int nbor_pitch,
const __global numtyp4 *restrict v_, const __global numtyp4 *restrict v_,
const int dimension, const int t_per_atom) { const int dimension, const int t_per_atom) {
int tid, ii, offset; int tid, ii, offset, i;
atom_info(t_per_atom,ii,tid,offset); atom_info(t_per_atom,ii,tid,offset);
int n_stride; int n_stride;
@ -80,10 +82,10 @@ __kernel void k_sph_taitwater(const __global numtyp4 *restrict x_,
for (int i=0; i<6; i++) virial[i]=(acctyp)0; for (int i=0; i<6; i++) virial[i]=(acctyp)0;
} }
acctyp2 drhoEacc; acctyp2 drhoEacc;
drhoEacc.x = drhoEacc.x = (acctyp)0; drhoEacc.x = drhoEacc.y = (acctyp)0;
if (ii<inum) { if (ii<inum) {
int i, numj, nbor, nbor_end; int numj, nbor, nbor_end;
nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj, nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
n_stride,nbor_end,nbor); n_stride,nbor_end,nbor);
@ -163,8 +165,7 @@ __kernel void k_sph_taitwater(const __global numtyp4 *restrict x_,
numtyp fvisc = (numtyp)0; numtyp fvisc = (numtyp)0;
if (delVdotDelR < (numtyp)0) { if (delVdotDelR < (numtyp)0) {
numtyp mu = h * delVdotDelR / (rsq + (numtyp)0.01 * h * h); numtyp mu = h * delVdotDelR / (rsq + (numtyp)0.01 * h * h);
fvisc = -coeffx * (soundspeed_itype fvisc = -coeffx * (soundspeed_itype + soundspeed_jtype) * mu / (rhoi + rhoj);
+ soundspeed_jtype) * mu / (rhoi + rhoj);
} }
// total pair force & thermal energy increment // total pair force & thermal energy increment
@ -176,15 +177,11 @@ __kernel void k_sph_taitwater(const __global numtyp4 *restrict x_,
f.z+=delz*force; f.z+=delz*force;
// and change in density, drho[i] // and change in density, drho[i]
drhoEacc.x += mass_jtype* delVdotDelR * wfd; drhoEacc.x += mass_jtype * delVdotDelR * wfd;
// change in thermal energy, desph[i] // change in thermal energy, desph[i]
drhoEacc.y += deltaE; drhoEacc.y += deltaE;
if (EVFLAG && eflag) {
numtyp e = (numtyp)0;
energy+=e;
}
if (EVFLAG && vflag) { if (EVFLAG && vflag) {
virial[0] += delx*delx*force; virial[0] += delx*delx*force;
virial[1] += dely*dely*force; virial[1] += dely*dely*force;
@ -198,7 +195,7 @@ __kernel void k_sph_taitwater(const __global numtyp4 *restrict x_,
} // if ii } // if ii
store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag,
ans,engv); ans,engv);
store_drhoE(drhoEacc,ii,inum,tid,t_per_atom,offset,drhoE); store_drhoE(drhoEacc,ii,inum,tid,t_per_atom,offset,i,drhoE);
} }
__kernel void k_sph_taitwater_fast(const __global numtyp4 *restrict x_, __kernel void k_sph_taitwater_fast(const __global numtyp4 *restrict x_,
@ -210,12 +207,12 @@ __kernel void k_sph_taitwater_fast(const __global numtyp4 *restrict x_,
const __global int * dev_packed, const __global int * dev_packed,
__global acctyp3 *restrict ans, __global acctyp3 *restrict ans,
__global acctyp *restrict engv, __global acctyp *restrict engv,
__global acctyp2 *restrict drhoE, __global acctyp *restrict drhoE,
const int eflag, const int vflag, const int eflag, const int vflag,
const int inum, const int nbor_pitch, const int inum, const int nbor_pitch,
const __global numtyp4 *restrict v_, const __global numtyp4 *restrict v_,
const int dimension, const int t_per_atom) { const int dimension, const int t_per_atom) {
int tid, ii, offset; int tid, ii, offset, i;
atom_info(t_per_atom,ii,tid,offset); atom_info(t_per_atom,ii,tid,offset);
#ifndef ONETYPE #ifndef ONETYPE
@ -245,10 +242,10 @@ __kernel void k_sph_taitwater_fast(const __global numtyp4 *restrict x_,
for (int i=0; i<6; i++) virial[i]=(acctyp)0; for (int i=0; i<6; i++) virial[i]=(acctyp)0;
} }
acctyp2 drhoEacc; acctyp2 drhoEacc;
drhoEacc.x = drhoEacc.x = (acctyp)0; drhoEacc.x = drhoEacc.y = (acctyp)0;
if (ii<inum) { if (ii<inum) {
int i, numj, nbor, nbor_end; int numj, nbor, nbor_end;
nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj, nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
n_stride,nbor_end,nbor); n_stride,nbor_end,nbor);
@ -337,8 +334,7 @@ __kernel void k_sph_taitwater_fast(const __global numtyp4 *restrict x_,
numtyp fvisc = (numtyp)0; numtyp fvisc = (numtyp)0;
if (delVdotDelR < (numtyp)0) { if (delVdotDelR < (numtyp)0) {
numtyp mu = h * delVdotDelR / (rsq + (numtyp)0.01 * h * h); numtyp mu = h * delVdotDelR / (rsq + (numtyp)0.01 * h * h);
fvisc = -coeffx * (soundspeed_itype fvisc = -coeffx * (soundspeed_itype + soundspeed_jtype) * mu / (rhoi + rhoj);
+ soundspeed_jtype) * mu / (rhoi + rhoj);
} }
// total pair force & thermal energy increment // total pair force & thermal energy increment
@ -349,16 +345,12 @@ __kernel void k_sph_taitwater_fast(const __global numtyp4 *restrict x_,
f.y+=dely*force; f.y+=dely*force;
f.z+=delz*force; f.z+=delz*force;
// and change in density // and change in density, drho[i]
drhoEacc.x += mass_jtype * delVdotDelR * wfd; drhoEacc.x += mass_jtype * delVdotDelR * wfd;
// change in thermal energy // change in thermal energy, desph[i]
drhoEacc.y += deltaE; drhoEacc.y += deltaE;
if (EVFLAG && eflag) {
numtyp e = (numtyp)0;
energy+=e;
}
if (EVFLAG && vflag) { if (EVFLAG && vflag) {
virial[0] += delx*delx*force; virial[0] += delx*delx*force;
virial[1] += dely*dely*force; virial[1] += dely*dely*force;
@ -372,6 +364,6 @@ __kernel void k_sph_taitwater_fast(const __global numtyp4 *restrict x_,
} // if ii } // if ii
store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, ans,engv); store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag, ans,engv);
store_drhoE(drhoEacc,ii,inum,tid,t_per_atom,offset,drhoE); store_drhoE(drhoEacc,ii,inum,tid,t_per_atom,offset,i,drhoE);
} }

View File

@ -1078,15 +1078,23 @@ class lammps(object):
def extract_fix(self,fid,fstyle,ftype,nrow=0,ncol=0): def extract_fix(self,fid,fstyle,ftype,nrow=0,ncol=0):
"""Retrieve data from a LAMMPS fix """Retrieve data from a LAMMPS fix
This is a wrapper around the :cpp:func:`lammps_extract_fix` This is a wrapper around the :cpp:func:`lammps_extract_fix` function
function of the C-library interface. of the C-library interface. This function returns ``None`` if
This function returns ``None`` if either the fix id is not either the fix id is not recognized, or an invalid combination of
recognized, or an invalid combination of :ref:`fstyle <py_style_constants>` :ref:`fstyle <py_style_constants>` and :ref:`ftype
and :ref:`ftype <py_type_constants>` constants is used. The <py_type_constants>` constants is used. The names and functionality
names and functionality of the constants are the same as for of the constants are the same as for the corresponding C-library
the corresponding C-library function. For requests to return function. For requests to return a scalar or a size, the value is
a scalar or a size, the value is returned, also when accessing returned, also when accessing global vectors or arrays, otherwise a
global vectors or arrays, otherwise a pointer. pointer.
.. note::
When requesting global data, the fix data can only be accessed
one item at a time without access to the whole vector or array.
Thus this function will always return a scalar. To access vector
or array elements the "nrow" and "ncol" arguments need to be set
accordingly (they default to 0).
:param fid: fix ID :param fid: fix ID
:type fid: string :type fid: string

View File

@ -203,6 +203,13 @@ class numpy_wrapper:
It behaves the same as the original method, but returns NumPy arrays It behaves the same as the original method, but returns NumPy arrays
instead of ``ctypes`` pointers. instead of ``ctypes`` pointers.
.. note::
When requesting global data, the fix data can only be accessed one
item at a time without access to the whole vector or array. Thus this
function will always return a scalar. To access vector or array elements
the "nrow" and "ncol" arguments need to be set accordingly (they default to 0).
:param fid: fix ID :param fid: fix ID
:type fid: string :type fid: string
:param fstyle: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants` :param fstyle: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`

View File

@ -16,7 +16,6 @@
Contributing author: Andres Jaramillo-Botero (Caltech) Contributing author: Andres Jaramillo-Botero (Caltech)
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#include "fix_nh_eff.h" #include "fix_nh_eff.h"
#include "atom.h" #include "atom.h"
@ -62,7 +61,7 @@ void FixNHEff::nve_v()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
if (abs(spin[i])==1) { if (abs(spin[i])==1) {
dtfm = dtf / mass[type[i]]; dtfm = dtf / mass[type[i]];
ervel[i] = dtfm * erforce[i] / mefactor; ervel[i] += dtfm * erforce[i] / mefactor;
} }
} }
} }
@ -79,15 +78,26 @@ void FixNHEff::nve_x()
FixNH::nve_x(); FixNH::nve_x();
double *eradius = atom->eradius; double *eradius = atom->eradius;
double *erforce = atom->erforce;
double *ervel = atom->ervel; double *ervel = atom->ervel;
double *mass = atom->mass;
int *type = atom->type;
int *spin = atom->spin; int *spin = atom->spin;
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (igroup == atom->firstgroup) nlocal = atom->nfirst; if (igroup == atom->firstgroup) nlocal = atom->nfirst;
double mefactor = domain->dimension/4.0;
double dtfm;
for (int i = 0; i < nlocal; i++) for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) if (mask[i] & groupbit) {
if (abs(spin[i])==1) eradius[i] += dtv * ervel[i]; dtfm = dtf / mass[type[i]];
if (abs(spin[i])==1) {
ervel[i] += dtfm * erforce[i] / mefactor;
eradius[i] += dtv * ervel[i];
}
}
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -113,7 +113,7 @@ void PairSPHHeatConductionGPU::compute(int eflag, int vflag)
neighbor->ago, inum, nall, atom->x, atom->type, neighbor->ago, inum, nall, atom->x, atom->type,
sublo, subhi, atom->tag, atom->nspecial, atom->special, eflag, vflag, sublo, subhi, atom->tag, atom->nspecial, atom->special, eflag, vflag,
eflag_atom, vflag_atom, host_start, &ilist, &numneigh, eflag_atom, vflag_atom, host_start, &ilist, &numneigh,
cpu_time, success, atom->v); cpu_time, success, atom->vest);
} else { } else {
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
@ -122,7 +122,7 @@ void PairSPHHeatConductionGPU::compute(int eflag, int vflag)
sph_heatconduction_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, sph_heatconduction_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type,
ilist, numneigh, firstneigh, eflag, vflag, ilist, numneigh, firstneigh, eflag, vflag,
eflag_atom, vflag_atom, host_start, cpu_time, success, eflag_atom, vflag_atom, host_start, cpu_time, success,
atom->tag, atom->v); atom->tag, atom->vest);
} }
if (!success) error->one(FLERR, "Insufficient memory on accelerator"); if (!success) error->one(FLERR, "Insufficient memory on accelerator");

View File

@ -114,7 +114,7 @@ void PairSPHLJGPU::compute(int eflag, int vflag)
neighbor->ago, inum, nall, atom->x, atom->type, neighbor->ago, inum, nall, atom->x, atom->type,
sublo, subhi, atom->tag, atom->nspecial, atom->special, eflag, vflag, sublo, subhi, atom->tag, atom->nspecial, atom->special, eflag, vflag,
eflag_atom, vflag_atom, host_start, &ilist, &numneigh, eflag_atom, vflag_atom, host_start, &ilist, &numneigh,
cpu_time, success, atom->v); cpu_time, success, atom->vest);
} else { } else {
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
@ -123,7 +123,7 @@ void PairSPHLJGPU::compute(int eflag, int vflag)
sph_lj_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, sph_lj_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type,
ilist, numneigh, firstneigh, eflag, vflag, ilist, numneigh, firstneigh, eflag, vflag,
eflag_atom, vflag_atom, host_start, cpu_time, success, eflag_atom, vflag_atom, host_start, cpu_time, success,
atom->tag, atom->v); atom->tag, atom->vest);
} }
if (!success) error->one(FLERR, "Insufficient memory on accelerator"); if (!success) error->one(FLERR, "Insufficient memory on accelerator");
@ -136,21 +136,21 @@ void PairSPHLJGPU::compute(int eflag, int vflag)
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (acc_float) { if (acc_float) {
auto drhoE_ptr = (float *)drhoE_pinned; auto drhoE_ptr = (float *)drhoE_pinned;
int idx = 0; for (int i = 0; i < nlocal; i++)
for (int i = 0; i < nlocal; i++) { drho[i] += drhoE_ptr[i];
drho[i] = drhoE_ptr[idx];
desph[i] = drhoE_ptr[idx+1]; drhoE_ptr += nlocal;
idx += 2; for (int i = 0; i < nlocal; i++)
} desph[i] += drhoE_ptr[i];
} else { } else {
auto drhoE_ptr = (double *)drhoE_pinned; auto drhoE_ptr = (double *)drhoE_pinned;
int idx = 0; for (int i = 0; i < nlocal; i++)
for (int i = 0; i < nlocal; i++) { drho[i] += drhoE_ptr[i];
drho[i] = drhoE_ptr[idx];
desph[i] = drhoE_ptr[idx+1]; drhoE_ptr += nlocal;
idx += 2; for (int i = 0; i < nlocal; i++)
} desph[i] += drhoE_ptr[i];
} }
if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0) if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0)

View File

@ -18,6 +18,7 @@
#include "pair_sph_taitwater_gpu.h" #include "pair_sph_taitwater_gpu.h"
#include "atom.h" #include "atom.h"
#include "comm.h"
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "force.h" #include "force.h"
@ -85,6 +86,25 @@ void PairSPHTaitwaterGPU::compute(int eflag, int vflag)
{ {
ev_init(eflag, vflag); ev_init(eflag, vflag);
// check consistency of pair coefficients
if (first) {
for (int i = 1; i <= atom->ntypes; i++) {
for (int j = 1; i <= atom->ntypes; i++) {
if (cutsq[i][j] > 1.e-32) {
if (!setflag[i][i] || !setflag[j][j]) {
if (comm->me == 0) {
printf(
"SPH particle types %d and %d interact with cutoff=%g, but not all of their single particle properties are set.\n",
i, j, sqrt(cutsq[i][j]));
}
}
}
}
}
first = 0;
}
int nall = atom->nlocal + atom->nghost; int nall = atom->nlocal + atom->nghost;
int inum, host_start; int inum, host_start;
@ -110,7 +130,7 @@ void PairSPHTaitwaterGPU::compute(int eflag, int vflag)
firstneigh = sph_taitwater_gpu_compute_n( firstneigh = sph_taitwater_gpu_compute_n(
neighbor->ago, inum, nall, atom->x, atom->type, sublo, subhi, atom->tag, atom->nspecial, neighbor->ago, inum, nall, atom->x, atom->type, sublo, subhi, atom->tag, atom->nspecial,
atom->special, eflag, vflag, eflag_atom, vflag_atom, host_start, &ilist, &numneigh, atom->special, eflag, vflag, eflag_atom, vflag_atom, host_start, &ilist, &numneigh,
cpu_time, success, atom->v); cpu_time, success, atom->vest);
} else { } else {
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
@ -118,7 +138,7 @@ void PairSPHTaitwaterGPU::compute(int eflag, int vflag)
firstneigh = list->firstneigh; firstneigh = list->firstneigh;
sph_taitwater_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, ilist, numneigh, firstneigh, sph_taitwater_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type, ilist, numneigh, firstneigh,
eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time, success, eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time, success,
atom->tag, atom->v); atom->tag, atom->vest);
} }
if (!success) error->one(FLERR, "Insufficient memory on accelerator"); if (!success) error->one(FLERR, "Insufficient memory on accelerator");
@ -131,21 +151,21 @@ void PairSPHTaitwaterGPU::compute(int eflag, int vflag)
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (acc_float) { if (acc_float) {
auto drhoE_ptr = (float *)drhoE_pinned; auto drhoE_ptr = (float *)drhoE_pinned;
int idx = 0; for (int i = 0; i < nlocal; i++)
for (int i = 0; i < nlocal; i++) { drho[i] += drhoE_ptr[i];
drho[i] = drhoE_ptr[idx];
desph[i] = drhoE_ptr[idx+1]; drhoE_ptr += nlocal;
idx += 2; for (int i = 0; i < nlocal; i++)
} desph[i] += drhoE_ptr[i];
} else { } else {
auto drhoE_ptr = (double *)drhoE_pinned; auto drhoE_ptr = (double *)drhoE_pinned;
int idx = 0; for (int i = 0; i < nlocal; i++)
for (int i = 0; i < nlocal; i++) { drho[i] += drhoE_ptr[i];
drho[i] = drhoE_ptr[idx];
desph[i] = drhoE_ptr[idx+1]; drhoE_ptr += nlocal;
idx += 2; for (int i = 0; i < nlocal; i++)
} desph[i] += drhoE_ptr[i];
} }
if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0) if (atom->molecular != Atom::ATOMIC && neighbor->ago == 0)

View File

@ -950,6 +950,8 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, std::enable_if_t<(NEIGHFLAG&P
static int vectorsize = 0; static int vectorsize = 0;
static int atoms_per_team = 0; static int atoms_per_team = 0;
static int teamsize_max_for = 0;
static int teamsize_max_reduce = 0;
#if defined(LMP_KOKKOS_GPU) #if defined(LMP_KOKKOS_GPU)
static int lastcall = -1; static int lastcall = -1;
@ -966,7 +968,6 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, std::enable_if_t<(NEIGHFLAG&P
vectorsize = MIN(vectorsize,max_vectorsize); vectorsize = MIN(vectorsize,max_vectorsize);
int teamsize_max_for,teamsize_max_reduce;
if (fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) { if (fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) {
PairComputeFunctor<PairStyle,NEIGHFLAG,false,ZEROFLAG,Specialisation > ff(fpair,list); PairComputeFunctor<PairStyle,NEIGHFLAG,false,ZEROFLAG,Specialisation > ff(fpair,list);
GetMaxTeamSize<typename PairStyle::device_type>(ff, inum, teamsize_max_for, teamsize_max_reduce); GetMaxTeamSize<typename PairStyle::device_type>(ff, inum, teamsize_max_for, teamsize_max_reduce);
@ -974,12 +975,12 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, std::enable_if_t<(NEIGHFLAG&P
PairComputeFunctor<PairStyle,NEIGHFLAG,true,ZEROFLAG,Specialisation > ff(fpair,list); PairComputeFunctor<PairStyle,NEIGHFLAG,true,ZEROFLAG,Specialisation > ff(fpair,list);
GetMaxTeamSize<typename PairStyle::device_type>(ff, inum, teamsize_max_for, teamsize_max_reduce); GetMaxTeamSize<typename PairStyle::device_type>(ff, inum, teamsize_max_for, teamsize_max_reduce);
} }
}
int teamsize_max = teamsize_max_for; int teamsize_max = teamsize_max_for;
if (fpair->eflag || fpair->vflag) if (fpair->eflag || fpair->vflag)
teamsize_max = teamsize_max_reduce; teamsize_max = teamsize_max_reduce;
atoms_per_team = teamsize_max/vectorsize; atoms_per_team = teamsize_max/vectorsize;
}
#else #else
vectorsize = 1; vectorsize = 1;
atoms_per_team = 1; atoms_per_team = 1;

View File

@ -253,11 +253,9 @@ void FixSemiGrandCanonicalMC::init()
error->all(FLERR, "Can not run fix sgcmc with naive total energy calculation " error->all(FLERR, "Can not run fix sgcmc with naive total energy calculation "
"and more than one MPI process."); "and more than one MPI process.");
// Create a compute that will provide the total energy of the system. // Get reference to a compute that will provide the total energy of the system.
// This is needed by computeTotalEnergy(). // This is needed by computeTotalEnergy().
char* id_pe = (char*)"thermo_pe"; compute_pe = modify->get_compute_by_id("thermo_pe");
int ipe = modify->find_compute(id_pe);
compute_pe = modify->compute[ipe];
} }
interactionRadius = force->pair->cutforce; interactionRadius = force->pair->cutforce;
if (comm->me == 0) utils::logmesg(lmp, " SGC - Interaction radius: {}\n", interactionRadius); if (comm->me == 0) utils::logmesg(lmp, " SGC - Interaction radius: {}\n", interactionRadius);
@ -373,8 +371,7 @@ void FixSemiGrandCanonicalMC::doMC()
// Use a random number to choose the new species if there are three or more atom types. // Use a random number to choose the new species if there are three or more atom types.
newSpecies = (int)(localRandom->uniform() * (atom->ntypes-1)) + 1; newSpecies = (int)(localRandom->uniform() * (atom->ntypes-1)) + 1;
if (newSpecies >= oldSpecies) newSpecies++; if (newSpecies >= oldSpecies) newSpecies++;
} } else {
else {
// If there are only two atom types, then the decision is clear. // If there are only two atom types, then the decision is clear.
newSpecies = (oldSpecies == 1) ? 2 : 1; newSpecies = (oldSpecies == 1) ? 2 : 1;
} }
@ -394,8 +391,7 @@ void FixSemiGrandCanonicalMC::doMC()
if (serialMode && kappa != 0.0) { if (serialMode && kappa != 0.0) {
for (int i = 2; i <= atom->ntypes; i++) for (int i = 2; i <= atom->ntypes; i++)
dm += (deltamu[i] + kappa / atom->natoms * (2.0 * speciesCounts[i] + deltaN[i])) * deltaN[i]; dm += (deltamu[i] + kappa / atom->natoms * (2.0 * speciesCounts[i] + deltaN[i])) * deltaN[i];
} } else {
else {
for (int i = 2; i <= atom->ntypes; i++) for (int i = 2; i <= atom->ntypes; i++)
dm += deltamu[i] * deltaN[i]; dm += deltamu[i] * deltaN[i];
} }
@ -436,8 +432,7 @@ void FixSemiGrandCanonicalMC::doMC()
// Update global species counters. // Update global species counters.
for (int i = 1; i <= atom->ntypes; i++) for (int i = 1; i <= atom->ntypes; i++)
speciesCounts[i] += deltaNGlobal[i]; speciesCounts[i] += deltaNGlobal[i];
} } else if (serialMode) {
else if (serialMode) {
// Update the local species counters. // Update the local species counters.
for (int i = 1; i <= atom->ntypes; i++) for (int i = 1; i <= atom->ntypes; i++)
speciesCounts[i] += deltaN[i]; speciesCounts[i] += deltaN[i];
@ -450,8 +445,7 @@ void FixSemiGrandCanonicalMC::doMC()
else else
flipAtomGeneric(selectedAtom, oldSpecies, newSpecies); flipAtomGeneric(selectedAtom, oldSpecies, newSpecies);
nAcceptedSwapsLocal++; nAcceptedSwapsLocal++;
} } else {
else {
nRejectedSwapsLocal++; nRejectedSwapsLocal++;
} }

View File

@ -47,10 +47,10 @@
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
using namespace FixConst; using namespace FixConst;
using MathConst::MY_PI;
using MathConst::MY_2PI; using MathConst::MY_2PI;
using MathConst::THIRD; using MathConst::MY_PI;
using MathConst::MY_SQRT2; using MathConst::MY_SQRT2;
using MathConst::THIRD;
using MathSpecial::powint; using MathSpecial::powint;
enum { PIMD, NMPIMD }; enum { PIMD, NMPIMD };
@ -475,11 +475,13 @@ void FixPIMDLangevin::init()
c_pe = modify->get_compute_by_id(id_pe); c_pe = modify->get_compute_by_id(id_pe);
if (!c_pe) if (!c_pe)
error->universe_all(FLERR, fmt::format("Could not find fix {} potential energy compute ID {}", style, id_pe)); error->universe_all(
FLERR, fmt::format("Could not find fix {} potential energy compute ID {}", style, id_pe));
c_press = modify->get_compute_by_id(id_press); c_press = modify->get_compute_by_id(id_press);
if (!c_press) if (!c_press)
error->universe_all(FLERR, fmt::format("Could not find fix {} pressure compute ID {}", style, id_press)); error->universe_all(
FLERR, fmt::format("Could not find fix {} pressure compute ID {}", style, id_press));
t_prim = t_vir = t_cv = p_prim = p_vir = p_cv = p_md = 0.0; t_prim = t_vir = t_cv = p_prim = p_vir = p_cv = p_md = 0.0;
} }
@ -667,7 +669,6 @@ void FixPIMDLangevin::post_force(int /*flag*/)
imageint *image = atom->image; imageint *image = atom->image;
tagint *tag = atom->tag; tagint *tag = atom->tag;
if (method == NMPIMD) {
if (atom->nmax > maxunwrap) reallocate_x_unwrap(); if (atom->nmax > maxunwrap) reallocate_x_unwrap();
if (atom->nmax > maxxc) reallocate_xc(); if (atom->nmax > maxxc) reallocate_xc();
for (int i = 0; i < nlocal; i++) { for (int i = 0; i < nlocal; i++) {
@ -685,9 +686,9 @@ void FixPIMDLangevin::post_force(int /*flag*/)
} }
compute_vir(); compute_vir();
compute_xf_vir();
compute_cvir(); compute_cvir();
compute_t_vir(); compute_t_vir();
}
if (method == PIMD) { if (method == PIMD) {
if (mapflag) { if (mapflag) {
@ -696,6 +697,7 @@ void FixPIMDLangevin::post_force(int /*flag*/)
inter_replica_comm(x); inter_replica_comm(x);
spring_force(); spring_force();
compute_spring_energy(); compute_spring_energy();
compute_t_prim();
if (mapflag) { if (mapflag) {
for (int i = 0; i < nlocal; i++) { domain->unmap_inv(x[i], image[i]); } for (int i = 0; i < nlocal; i++) { domain->unmap_inv(x[i], image[i]); }
} }
@ -741,7 +743,7 @@ void FixPIMDLangevin::collect_xc()
} }
} }
const double sqrtnp = sqrt((double)np); const double sqrtnp = sqrt((double) np);
for (int i = 0; i < nlocal; i++) { for (int i = 0; i < nlocal; i++) {
xcall[3 * (tag[i] - 1) + 0] = x[i][0] / sqrtnp; xcall[3 * (tag[i] - 1) + 0] = x[i][0] / sqrtnp;
xcall[3 * (tag[i] - 1) + 1] = x[i][1] / sqrtnp; xcall[3 * (tag[i] - 1) + 1] = x[i][1] / sqrtnp;
@ -1048,8 +1050,8 @@ void FixPIMDLangevin::langevin_init()
c2_k[i] = sqrt(1.0 - c1_k[i] * c1_k[i]); c2_k[i] = sqrt(1.0 - c1_k[i] * c1_k[i]);
} }
for (int i = 0; i < np; i++) { for (int i = 0; i < np; i++) {
out += fmt::format(" {:d} {:.8e} {:.8e} {:.8e} {:.8e}\n", i, out += fmt::format(" {:d} {:.8e} {:.8e} {:.8e} {:.8e}\n", i, _omega_k[i], tau_k[i],
_omega_k[i], tau_k[i], c1_k[i], c2_k[i]); c1_k[i], c2_k[i]);
} }
} else if (method == PIMD) { } else if (method == PIMD) {
for (int i = 0; i < np; i++) { for (int i = 0; i < np; i++) {
@ -1111,7 +1113,7 @@ void FixPIMDLangevin::nmpimd_init()
} }
// Set up eigenvectors for degenerated modes // Set up eigenvectors for degenerated modes
const double sqrtnp = sqrt((double)np); const double sqrtnp = sqrt((double) np);
for (int j = 0; j < np; j++) { for (int j = 0; j < np; j++) {
for (int i = 1; i < int(np / 2) + 1; i++) { for (int i = 1; i < int(np / 2) + 1; i++) {
M_x2xp[i][j] = MY_SQRT2 * cos(MY_2PI * double(i) * double(j) / double(np)) / sqrtnp; M_x2xp[i][j] = MY_SQRT2 * cos(MY_2PI * double(i) * double(j) / double(np)) / sqrtnp;
@ -1364,6 +1366,7 @@ void FixPIMDLangevin::inter_replica_comm(double **ptr)
void FixPIMDLangevin::remove_com_motion() void FixPIMDLangevin::remove_com_motion()
{ {
if (method == NMPIMD) {
if (universe->iworld == 0) { if (universe->iworld == 0) {
double **v = atom->v; double **v = atom->v;
int *mask = atom->mask; int *mask = atom->mask;
@ -1379,6 +1382,36 @@ void FixPIMDLangevin::remove_com_motion()
} }
} }
} }
} else if (method == PIMD) {
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (dynamic) masstotal = group->mass(igroup);
double vcm[3];
group->vcm(igroup, masstotal, vcm);
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
v[i][0] -= vcm[0];
v[i][1] -= vcm[1];
v[i][2] -= vcm[2];
}
}
} else {
error->all(FLERR, "Unknown method for fix pimd/langevin. Only nmpimd and pimd are supported!");
}
}
/* ---------------------------------------------------------------------- */
void FixPIMDLangevin::compute_xf_vir()
{
int nlocal = atom->nlocal;
double xf = 0.0;
vir_ = 0.0;
for (int i = 0; i < nlocal; i++) {
for (int j = 0; j < 3; j++) { xf += x_unwrap[i][j] * atom->f[i][j]; }
}
MPI_Allreduce(&xf, &vir_, 1, MPI_DOUBLE, MPI_SUM, universe->uworld);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -1386,16 +1419,11 @@ void FixPIMDLangevin::remove_com_motion()
void FixPIMDLangevin::compute_cvir() void FixPIMDLangevin::compute_cvir()
{ {
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
double xf = 0.0;
double xcf = 0.0; double xcf = 0.0;
vir_ = centroid_vir = 0.0; centroid_vir = 0.0;
for (int i = 0; i < nlocal; i++) { for (int i = 0; i < nlocal; i++) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) { xcf += (x_unwrap[i][j] - xc[i][j]) * atom->f[i][j]; }
xf += x_unwrap[i][j] * atom->f[i][j];
xcf += (x_unwrap[i][j] - xc[i][j]) * atom->f[i][j];
} }
}
MPI_Allreduce(&xf, &vir_, 1, MPI_DOUBLE, MPI_SUM, universe->uworld);
MPI_Allreduce(&xcf, &centroid_vir, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); MPI_Allreduce(&xcf, &centroid_vir, 1, MPI_DOUBLE, MPI_SUM, universe->uworld);
if (pstyle == ANISO) { if (pstyle == ANISO) {
for (int i = 0; i < 6; i++) c_vir_tensor[i] = 0.0; for (int i = 0; i < 6; i++) c_vir_tensor[i] = 0.0;
@ -1553,11 +1581,19 @@ void FixPIMDLangevin::compute_p_prim()
void FixPIMDLangevin::compute_p_cv() void FixPIMDLangevin::compute_p_cv()
{ {
double inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); double inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd);
p_md = THIRD * inv_volume * (totke + vir);
if (method == NMPIMD) {
if (universe->iworld == 0) { if (universe->iworld == 0) {
p_cv = THIRD * inv_volume * ((2.0 * ke_bead - centroid_vir) * force->nktv2p + vir) / np; p_cv = THIRD * inv_volume * ((2.0 * ke_bead - centroid_vir) * force->nktv2p + vir) / np;
} }
p_md = THIRD * inv_volume * (totke + vir);
MPI_Bcast(&p_cv, 1, MPI_DOUBLE, 0, universe->uworld); MPI_Bcast(&p_cv, 1, MPI_DOUBLE, 0, universe->uworld);
} else if (method == PIMD) {
p_cv = THIRD * inv_volume * ((2.0 * totke / np - centroid_vir) * force->nktv2p + vir) / np;
} else {
error->universe_all(
FLERR,
"Unknown method parameter for fix pimd/langevin. Only nmpimd and pimd are supported!");
}
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */

View File

@ -176,6 +176,7 @@ class FixPIMDLangevin : public Fix {
void compute_p_prim(); void compute_p_prim();
void compute_p_cv(); // centroid-virial pressure estimator void compute_p_cv(); // centroid-virial pressure estimator
void compute_vir(); void compute_vir();
void compute_xf_vir();
void compute_cvir(); void compute_cvir();
void compute_totenthalpy(); void compute_totenthalpy();

View File

@ -215,10 +215,9 @@ void ComputeSpin::compute_vector()
tempnum += tx*tx+ty*ty+tz*tz; tempnum += tx*tx+ty*ty+tz*tz;
tempdenom += sp[i][0]*fm[i][0]+fm[i][1]*sp[i][1]+sp[i][2]*fm[i][2]; tempdenom += sp[i][0]*fm[i][0]+fm[i][1]*sp[i][1]+sp[i][2]*fm[i][2];
countsp++; countsp++;
} else error->all(FLERR,"Compute compute/spin requires atom/spin style");
} }
} }
else error->all(FLERR,"Compute compute/spin requires atom/spin style");
}
MPI_Allreduce(mag,magtot,4,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(mag,magtot,4,MPI_DOUBLE,MPI_SUM,world);
MPI_Allreduce(&magenergy,&magenergytot,1,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&magenergy,&magenergytot,1,MPI_DOUBLE,MPI_SUM,world);

View File

@ -270,7 +270,7 @@ void AngleHybrid::coeff(int narg, char **arg)
else if (strcmp(arg[1], "bb") == 0) else if (strcmp(arg[1], "bb") == 0)
error->all(FLERR, "BondBond coeff for hybrid angle has invalid format"); error->all(FLERR, "BondBond coeff for hybrid angle has invalid format");
else else
error->all(FLERR, "Angle coeff for hybrid has invalid style"); error->all(FLERR, "Expected hybrid sub-style instead of {} in angle_coeff command", arg[1]);
} }
// move 1st arg to 2nd arg // move 1st arg to 2nd arg

View File

@ -305,7 +305,7 @@ void BondHybrid::coeff(int narg, char **arg)
if (strcmp(arg[1], "none") == 0) if (strcmp(arg[1], "none") == 0)
none = 1; none = 1;
else else
error->all(FLERR, "Bond coeff for hybrid has invalid style"); error->all(FLERR, "Expected hybrid sub-style instead of {} in bond_coeff command", arg[1]);
} }
// move 1st arg to 2nd arg // move 1st arg to 2nd arg

View File

@ -277,7 +277,8 @@ void DihedralHybrid::coeff(int narg, char **arg)
else if (strcmp(arg[1], "bb13") == 0) else if (strcmp(arg[1], "bb13") == 0)
error->all(FLERR, "BondBond13 coeff for hybrid dihedral has invalid format"); error->all(FLERR, "BondBond13 coeff for hybrid dihedral has invalid format");
else else
error->all(FLERR, "Dihedral coeff for hybrid has invalid style"); error->all(FLERR, "Expected hybrid sub-style instead of {} in dihedral_coeff command",
arg[1]);
} }
// move 1st arg to 2nd arg // move 1st arg to 2nd arg

View File

@ -193,10 +193,12 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) :
cdof = utils::numeric(FLERR,arg[iarg+1],false,lmp); cdof = utils::numeric(FLERR,arg[iarg+1],false,lmp);
iarg += 2; iarg += 2;
} else if (strcmp(arg[iarg],"file") == 0) { } else if ((strcmp(arg[iarg],"file") == 0) || (strcmp(arg[iarg],"append") == 0)) {
if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk file", error); if (iarg+2 > narg)
utils::missing_cmd_args(FLERR, std::string("fix ave/chunk ")+arg[iarg], error);
if (comm->me == 0) { if (comm->me == 0) {
fp = fopen(arg[iarg+1],"w"); if (strcmp(arg[iarg],"file") == 0) fp = fopen(arg[iarg+1],"w");
else fp = fopen(arg[iarg+1],"a");
if (fp == nullptr) if (fp == nullptr)
error->one(FLERR, "Cannot open fix ave/chunk file {}: {}", error->one(FLERR, "Cannot open fix ave/chunk file {}: {}",
arg[iarg+1], utils::getsyserror()); arg[iarg+1], utils::getsyserror());

View File

@ -839,10 +839,12 @@ void FixAveHisto::options(int iarg, int narg, char **arg)
auto mycmd = fmt::format("fix {}", style); auto mycmd = fmt::format("fix {}", style);
while (iarg < narg) { while (iarg < narg) {
if (strcmp(arg[iarg],"file") == 0) { if ((strcmp(arg[iarg],"file") == 0) || (strcmp(arg[iarg],"append") == 0)) {
if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " file", error); if (iarg+2 > narg)
utils::missing_cmd_args(FLERR, std::string("fix ave/histo ")+arg[iarg], error);
if (comm->me == 0) { if (comm->me == 0) {
fp = fopen(arg[iarg+1],"w"); if (strcmp(arg[iarg],"file") == 0) fp = fopen(arg[iarg+1],"w");
else fp = fopen(arg[iarg+1],"a");
if (fp == nullptr) if (fp == nullptr)
error->one(FLERR, "Cannot open fix ave/histo file {}: {}", error->one(FLERR, "Cannot open fix ave/histo file {}: {}",
arg[iarg+1], utils::getsyserror()); arg[iarg+1], utils::getsyserror());

View File

@ -1033,41 +1033,44 @@ void FixAveTime::options(int iarg, int narg, char **arg)
// optional args // optional args
while (iarg < narg) { while (iarg < narg) {
if (strcmp(arg[iarg],"file") == 0) { if ((strcmp(arg[iarg],"file") == 0) || (strcmp(arg[iarg],"append") == 0)) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (iarg+2 > narg)
utils::missing_cmd_args(FLERR, std::string("fix ave/time ")+arg[iarg], error);
yaml_flag = utils::strmatch(arg[iarg+1],"\\.[yY][aA]?[mM][lL]$"); yaml_flag = utils::strmatch(arg[iarg+1],"\\.[yY][aA]?[mM][lL]$");
if (comm->me == 0) { if (comm->me == 0) {
fp = fopen(arg[iarg+1],"w"); if (strcmp(arg[iarg],"file") == 0) fp = fopen(arg[iarg+1],"w");
else fp = fopen(arg[iarg+1],"a");
if (fp == nullptr) if (fp == nullptr)
error->one(FLERR,"Cannot open fix ave/time file {}: {}", error->one(FLERR,"Cannot open fix ave/time file {}: {}",
arg[iarg+1], utils::getsyserror()); arg[iarg+1], utils::getsyserror());
} }
iarg += 2; iarg += 2;
} else if (strcmp(arg[iarg],"ave") == 0) { } else if (strcmp(arg[iarg],"ave") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/time ave", error);
if (strcmp(arg[iarg+1],"one") == 0) ave = ONE; if (strcmp(arg[iarg+1],"one") == 0) ave = ONE;
else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING; else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING;
else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW; else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW;
else error->all(FLERR,"Illegal fix ave/time command"); else error->all(FLERR,"Unknown fix ave/time ave keyword {}", arg[iarg+1]);
if (ave == WINDOW) { if (ave == WINDOW) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (iarg+3 > narg) utils::missing_cmd_args(FLERR, "fix ave/time ave window", error);
nwindow = utils::inumeric(FLERR,arg[iarg+2],false,lmp); nwindow = utils::inumeric(FLERR,arg[iarg+2],false,lmp);
if (nwindow <= 0) error->all(FLERR,"Illegal fix ave/time command"); if (nwindow <= 0)
error->all(FLERR,"Illegal fix ave/time ave window argument {}; must be > 0", nwindow);
} }
iarg += 2; iarg += 2;
if (ave == WINDOW) iarg++; if (ave == WINDOW) iarg++;
} else if (strcmp(arg[iarg],"start") == 0) { } else if (strcmp(arg[iarg],"start") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/time start", error);
startstep = utils::inumeric(FLERR,arg[iarg+1],false,lmp); startstep = utils::inumeric(FLERR,arg[iarg+1],false,lmp);
iarg += 2; iarg += 2;
} else if (strcmp(arg[iarg],"mode") == 0) { } else if (strcmp(arg[iarg],"mode") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/time mode", error);
if (strcmp(arg[iarg+1],"scalar") == 0) mode = SCALAR; if (strcmp(arg[iarg+1],"scalar") == 0) mode = SCALAR;
else if (strcmp(arg[iarg+1],"vector") == 0) mode = VECTOR; else if (strcmp(arg[iarg+1],"vector") == 0) mode = VECTOR;
else error->all(FLERR,"Illegal fix ave/time command"); else error->all(FLERR,"Unknown fix ave/time mode {}", arg[iarg+1]);
iarg += 2; iarg += 2;
} else if (strcmp(arg[iarg],"off") == 0) { } else if (strcmp(arg[iarg],"off") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/time off", error);
memory->grow(offlist,noff+1,"ave/time:offlist"); memory->grow(offlist,noff+1,"ave/time:offlist");
offlist[noff++] = utils::inumeric(FLERR,arg[iarg+1],false,lmp); offlist[noff++] = utils::inumeric(FLERR,arg[iarg+1],false,lmp);
iarg += 2; iarg += 2;
@ -1075,27 +1078,27 @@ void FixAveTime::options(int iarg, int narg, char **arg)
overwrite = 1; overwrite = 1;
iarg += 1; iarg += 1;
} else if (strcmp(arg[iarg],"format") == 0) { } else if (strcmp(arg[iarg],"format") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/time format", error);
delete[] format_user; delete[] format_user;
format_user = utils::strdup(arg[iarg+1]); format_user = utils::strdup(arg[iarg+1]);
format = format_user; format = format_user;
iarg += 2; iarg += 2;
} else if (strcmp(arg[iarg],"title1") == 0) { } else if (strcmp(arg[iarg],"title1") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/time title1", error);
delete[] title1; delete[] title1;
title1 = utils::strdup(arg[iarg+1]); title1 = utils::strdup(arg[iarg+1]);
iarg += 2; iarg += 2;
} else if (strcmp(arg[iarg],"title2") == 0) { } else if (strcmp(arg[iarg],"title2") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/time title2", error);
delete[] title2; delete[] title2;
title2 = utils::strdup(arg[iarg+1]); title2 = utils::strdup(arg[iarg+1]);
iarg += 2; iarg += 2;
} else if (strcmp(arg[iarg],"title3") == 0) { } else if (strcmp(arg[iarg],"title3") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/time title3", error);
delete[] title3; delete[] title3;
title3 = utils::strdup(arg[iarg+1]); title3 = utils::strdup(arg[iarg+1]);
iarg += 2; iarg += 2;
} else error->all(FLERR,"Unknown fix ave/time command option {}", arg[iarg]); } else error->all(FLERR,"Unknown fix ave/time keyword {}", arg[iarg]);
} }
} }

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -14,6 +13,7 @@
#include "fix_print.h" #include "fix_print.h"
#include "comm.h"
#include "error.h" #include "error.h"
#include "input.h" #include "input.h"
#include "memory.h" #include "memory.h"
@ -29,24 +29,22 @@ using namespace FixConst;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) : FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), Fix(lmp, narg, arg), fp(nullptr), text(nullptr), copy(nullptr), work(nullptr),
fp(nullptr), text(nullptr), copy(nullptr), work(nullptr), var_print(nullptr) var_print(nullptr)
{ {
if (narg < 5) error->all(FLERR,"Illegal fix print command"); if (narg < 5) utils::missing_cmd_args(FLERR, "fix print", error);
if (utils::strmatch(arg[3],"^v_")) { if (utils::strmatch(arg[3], "^v_")) {
var_print = utils::strdup(arg[3]+2); var_print = utils::strdup(arg[3] + 2);
nevery = 1; nevery = 1;
} else { } else {
nevery = utils::inumeric(FLERR,arg[3],false,lmp); nevery = utils::inumeric(FLERR, arg[3], false, lmp);
if (nevery <= 0) error->all(FLERR,"Illegal fix print command"); if (nevery <= 0) error->all(FLERR, "Illegal fix print nevery value {}; must be > 0", nevery);
} }
MPI_Comm_rank(world,&me);
text = utils::strdup(arg[4]); text = utils::strdup(arg[4]);
int n = strlen(text)+1; int n = strlen(text) + 1;
copy = (char *) memory->smalloc(n*sizeof(char),"fix/print:copy"); copy = (char *) memory->smalloc(n * sizeof(char), "fix/print:copy");
work = (char *) memory->smalloc(n*sizeof(char),"fix/print:work"); work = (char *) memory->smalloc(n * sizeof(char), "fix/print:work");
maxcopy = maxwork = n; maxcopy = maxwork = n;
// parse optional args // parse optional args
@ -57,48 +55,54 @@ FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) :
int iarg = 5; int iarg = 5;
while (iarg < narg) { while (iarg < narg) {
if (strcmp(arg[iarg],"file") == 0 || strcmp(arg[iarg],"append") == 0) { if ((strcmp(arg[iarg], "file") == 0) || (strcmp(arg[iarg], "append") == 0)) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix print command"); if (iarg + 2 > narg)
if (me == 0) { utils::missing_cmd_args(FLERR, std::string("fix print ") + arg[iarg], error);
if (strcmp(arg[iarg],"file") == 0) fp = fopen(arg[iarg+1],"w"); if (comm->me == 0) {
else fp = fopen(arg[iarg+1],"a"); if (strcmp(arg[iarg], "file") == 0)
fp = fopen(arg[iarg + 1], "w");
else
fp = fopen(arg[iarg + 1], "a");
if (fp == nullptr) if (fp == nullptr)
error->one(FLERR,"Cannot open fix print file {}: {}", error->one(FLERR, "Cannot open fix print file {}: {}", arg[iarg + 1],
arg[iarg+1], utils::getsyserror()); utils::getsyserror());
} }
iarg += 2; iarg += 2;
} else if (strcmp(arg[iarg],"screen") == 0) { } else if (strcmp(arg[iarg], "screen") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix print command"); if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix print screen", error);
screenflag = utils::logical(FLERR,arg[iarg+1],false,lmp); screenflag = utils::logical(FLERR, arg[iarg + 1], false, lmp);
iarg += 2; iarg += 2;
} else if (strcmp(arg[iarg],"title") == 0) { } else if (strcmp(arg[iarg], "title") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix print command"); if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix print title", error);
delete [] title; delete[] title;
title = utils::strdup(arg[iarg+1]); title = utils::strdup(arg[iarg + 1]);
iarg += 2; iarg += 2;
} else error->all(FLERR,"Illegal fix print command"); } else
error->all(FLERR, "Unknown fix print keyword: {}", arg[iarg]);
} }
// print file comment line // print file comment line
if (fp && me == 0) { if (fp && (comm->me == 0)) {
if (title) fprintf(fp,"%s\n",title); if (title)
else fprintf(fp,"# Fix print output for fix %s\n",id); fprintf(fp, "%s\n", title);
else
fprintf(fp, "# Fix print output for fix %s\n", id);
} }
delete [] title; delete[] title;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
FixPrint::~FixPrint() FixPrint::~FixPrint()
{ {
delete [] text; delete[] text;
delete [] var_print; delete[] var_print;
memory->sfree(copy); memory->sfree(copy);
memory->sfree(work); memory->sfree(work);
if (fp && me == 0) fclose(fp); if (fp && (comm->me == 0)) fclose(fp);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -117,16 +121,16 @@ void FixPrint::init()
if (var_print) { if (var_print) {
ivar_print = input->variable->find(var_print); ivar_print = input->variable->find(var_print);
if (ivar_print < 0) if (ivar_print < 0)
error->all(FLERR,"Variable name for fix print timestep does not exist"); error->all(FLERR, "Variable {} for fix print timestep does not exist", var_print);
if (!input->variable->equalstyle(ivar_print)) if (!input->variable->equalstyle(ivar_print))
error->all(FLERR,"Variable for fix print timestep is invalid style"); error->all(FLERR, "Variable {} for fix print timestep is invalid style", var_print);
next_print = static_cast<bigint> next_print = static_cast<bigint>(input->variable->compute_equal(ivar_print));
(input->variable->compute_equal(ivar_print));
if (next_print <= update->ntimestep) if (next_print <= update->ntimestep)
error->all(FLERR,"Fix print timestep variable returned a bad timestep"); error->all(FLERR, "Fix print timestep variable {} returned a bad timestep: {}", var_print,
next_print);
} else { } else {
if (update->ntimestep % nevery) if (update->ntimestep % nevery)
next_print = (update->ntimestep/nevery)*nevery + nevery; next_print = (update->ntimestep / nevery) * nevery + nevery;
else else
next_print = update->ntimestep; next_print = update->ntimestep;
} }
@ -158,24 +162,23 @@ void FixPrint::end_of_step()
modify->clearstep_compute(); modify->clearstep_compute();
strncpy(copy,text,maxcopy); strncpy(copy, text, maxcopy);
input->substitute(copy,work,maxcopy,maxwork,0); input->substitute(copy, work, maxcopy, maxwork, 0);
if (var_print) { if (var_print) {
next_print = static_cast<bigint> next_print = static_cast<bigint>(input->variable->compute_equal(ivar_print));
(input->variable->compute_equal(ivar_print));
if (next_print <= update->ntimestep) if (next_print <= update->ntimestep)
error->all(FLERR,"Fix print timestep variable returned a bad timestep"); error->all(FLERR, "Fix print timestep variable returned a bad timestep: {}", next_print);
} else { } else {
next_print = (update->ntimestep/nevery)*nevery + nevery; next_print = (update->ntimestep / nevery) * nevery + nevery;
} }
modify->addstep_compute(next_print); modify->addstep_compute(next_print);
if (me == 0) { if (comm->me == 0) {
if (screenflag) utils::logmesg(lmp,std::string(copy) + "\n"); if (screenflag) utils::logmesg(lmp, std::string(copy) + "\n");
if (fp) { if (fp) {
fmt::print(fp,"{}\n",copy); fmt::print(fp, "{}\n", copy);
fflush(fp); fflush(fp);
} }
} }

View File

@ -34,7 +34,7 @@ class FixPrint : public Fix {
void end_of_step() override; void end_of_step() override;
private: private:
int me, screenflag; int screenflag;
FILE *fp; FILE *fp;
char *text, *copy, *work; char *text, *copy, *work;
int maxcopy, maxwork; int maxcopy, maxwork;

View File

@ -269,7 +269,8 @@ void ImproperHybrid::coeff(int narg, char **arg)
else if (strcmp(arg[1], "aa") == 0) else if (strcmp(arg[1], "aa") == 0)
error->all(FLERR, "AngleAngle coeff for hybrid improper has invalid format"); error->all(FLERR, "AngleAngle coeff for hybrid improper has invalid format");
else else
error->all(FLERR, "Improper coeff for hybrid has invalid style"); error->all(FLERR, "Expected hybrid sub-style instead of {} in improper_coeff command",
arg[1]);
} }
// move 1st arg to 2nd arg // move 1st arg to 2nd arg

View File

@ -2137,7 +2137,8 @@ available.
.. code-block:: c .. code-block:: c
double *dptr = (double *) lammps_extract_fix(handle,name,0,1,0,0); double *dptr = (double *) lammps_extract_fix(handle, name,
LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, 0, 0);
double value = *dptr; double value = *dptr;
lammps_free((void *)dptr); lammps_free((void *)dptr);
@ -2857,10 +2858,6 @@ void lammps_gather_atoms_concat(void *handle, const char *name, int type,
if ((count == 1) || imgunpack) vector = (int *) vptr; if ((count == 1) || imgunpack) vector = (int *) vptr;
else array = (int **) vptr; else array = (int **) vptr;
int *copy;
lmp->memory->create(copy,count*natoms,"lib/gather:copy");
for (i = 0; i < count*natoms; i++) copy[i] = 0;
int nlocal = lmp->atom->nlocal; int nlocal = lmp->atom->nlocal;
if (count == 1) { if (count == 1) {
@ -2868,11 +2865,13 @@ void lammps_gather_atoms_concat(void *handle, const char *name, int type,
displs[0] = 0; displs[0] = 0;
for (i = 1; i < nprocs; i++) for (i = 1; i < nprocs; i++)
displs[i] = displs[i-1] + recvcounts[i-1]; displs[i] = displs[i-1] + recvcounts[i-1];
MPI_Allgatherv(vector,nlocal,MPI_INT,data,recvcounts,displs, MPI_Allgatherv(vector,nlocal,MPI_INT,data,recvcounts,displs,MPI_INT,lmp->world);
MPI_INT,lmp->world);
} else if (imgunpack) { } else if (imgunpack) {
lmp->memory->create(copy,count*nlocal,"lib/gather:copy"); int *copy;
lmp->memory->create(copy,count*natoms,"lib/gather:copy");
for (i = 0; i < count*natoms; i++) copy[i] = 0;
offset = 0; offset = 0;
for (i = 0; i < nlocal; i++) { for (i = 0; i < nlocal; i++) {
const int image = vector[i]; const int image = vector[i];
@ -2885,8 +2884,7 @@ void lammps_gather_atoms_concat(void *handle, const char *name, int type,
displs[0] = 0; displs[0] = 0;
for (i = 1; i < nprocs; i++) for (i = 1; i < nprocs; i++)
displs[i] = displs[i-1] + recvcounts[i-1]; displs[i] = displs[i-1] + recvcounts[i-1];
MPI_Allgatherv(copy,count*nlocal,MPI_INT, MPI_Allgatherv(copy,count*nlocal,MPI_INT,data,recvcounts,displs,MPI_INT,lmp->world);
data,recvcounts,displs,MPI_INT,lmp->world);
lmp->memory->destroy(copy); lmp->memory->destroy(copy);
} else { } else {
@ -2895,8 +2893,7 @@ void lammps_gather_atoms_concat(void *handle, const char *name, int type,
displs[0] = 0; displs[0] = 0;
for (i = 1; i < nprocs; i++) for (i = 1; i < nprocs; i++)
displs[i] = displs[i-1] + recvcounts[i-1]; displs[i] = displs[i-1] + recvcounts[i-1];
MPI_Allgatherv(&array[0][0],count*nlocal,MPI_INT, MPI_Allgatherv(&array[0][0],count*nlocal,MPI_INT,data,recvcounts,displs,MPI_INT,lmp->world);
data,recvcounts,displs,MPI_INT,lmp->world);
} }
} else { } else {
@ -2912,8 +2909,7 @@ void lammps_gather_atoms_concat(void *handle, const char *name, int type,
displs[0] = 0; displs[0] = 0;
for (i = 1; i < nprocs; i++) for (i = 1; i < nprocs; i++)
displs[i] = displs[i-1] + recvcounts[i-1]; displs[i] = displs[i-1] + recvcounts[i-1];
MPI_Allgatherv(vector,nlocal,MPI_DOUBLE,data,recvcounts,displs, MPI_Allgatherv(vector,nlocal,MPI_DOUBLE,data,recvcounts,displs,MPI_DOUBLE,lmp->world);
MPI_DOUBLE,lmp->world);
} else { } else {
int n = count*nlocal; int n = count*nlocal;
@ -3171,10 +3167,6 @@ void lammps_scatter_atoms(void *handle, const char *name, int type, int count,
return; return;
} }
// copy = Natom length vector of per-atom values
// use atom ID to insert each atom's values into copy
// MPI_Allreduce with MPI_SUM to merge into data, ordered by atom ID
if (type == 0) { if (type == 0) {
int *vector = nullptr; int *vector = nullptr;
int **array = nullptr; int **array = nullptr;
@ -3322,10 +3314,6 @@ void lammps_scatter_atoms_subset(void *handle, const char *name, int type,
return; return;
} }
// copy = Natom length vector of per-atom values
// use atom ID to insert each atom's values into copy
// MPI_Allreduce with MPI_SUM to merge into data, ordered by atom ID
if (type == 0) { if (type == 0) {
int *vector = nullptr; int *vector = nullptr;
int **array = nullptr; int **array = nullptr;
@ -4328,10 +4316,6 @@ void lammps_gather_concat(void *handle, const char *name, int type, int count,
if ((count == 1) || imgunpack) vector = (int *) vptr; if ((count == 1) || imgunpack) vector = (int *) vptr;
else array = (int **) vptr; else array = (int **) vptr;
int *copy;
lmp->memory->create(copy,count*natoms,"lib/gather:copy");
for (i = 0; i < count*natoms; i++) copy[i] = 0;
int nlocal = lmp->atom->nlocal; int nlocal = lmp->atom->nlocal;
if (count == 1) { if (count == 1) {
@ -4343,7 +4327,10 @@ void lammps_gather_concat(void *handle, const char *name, int type, int count,
MPI_INT,lmp->world); MPI_INT,lmp->world);
} else if (imgunpack) { } else if (imgunpack) {
lmp->memory->create(copy,count*nlocal,"lib/gather:copy"); int *copy;
lmp->memory->create(copy,count*natoms,"lib/gather:copy");
for (i = 0; i < count*natoms; i++) copy[i] = 0;
offset = 0; offset = 0;
for (i = 0; i < nlocal; i++) { for (i = 0; i < nlocal; i++) {
const int image = vector[i]; const int image = vector[i];
@ -4356,8 +4343,7 @@ void lammps_gather_concat(void *handle, const char *name, int type, int count,
displs[0] = 0; displs[0] = 0;
for (i = 1; i < nprocs; i++) for (i = 1; i < nprocs; i++)
displs[i] = displs[i-1] + recvcounts[i-1]; displs[i] = displs[i-1] + recvcounts[i-1];
MPI_Allgatherv(copy,count*nlocal,MPI_INT, MPI_Allgatherv(copy,count*nlocal,MPI_INT,data,recvcounts,displs,MPI_INT,lmp->world);
data,recvcounts,displs,MPI_INT,lmp->world);
lmp->memory->destroy(copy); lmp->memory->destroy(copy);
} else { } else {
@ -4366,8 +4352,7 @@ void lammps_gather_concat(void *handle, const char *name, int type, int count,
displs[0] = 0; displs[0] = 0;
for (i = 1; i < nprocs; i++) for (i = 1; i < nprocs; i++)
displs[i] = displs[i-1] + recvcounts[i-1]; displs[i] = displs[i-1] + recvcounts[i-1];
MPI_Allgatherv(&array[0][0],count*nlocal,MPI_INT, MPI_Allgatherv(&array[0][0],count*nlocal,MPI_INT,data,recvcounts,displs,MPI_INT,lmp->world);
data,recvcounts,displs,MPI_INT,lmp->world);
} }
} else { } else {
@ -4876,10 +4861,6 @@ void lammps_scatter(void *handle, const char *name, int type, int count,
return; return;
} }
// copy = Natom length vector of per-atom values
// use atom ID to insert each atom's values into copy
// MPI_Allreduce with MPI_SUM to merge into data, ordered by atom ID
if (type == 0) { if (type == 0) {
int *vector = nullptr; int *vector = nullptr;
int **array = nullptr; int **array = nullptr;
@ -5130,10 +5111,6 @@ void lammps_scatter_subset(void *handle, const char *name,int type, int count,
return; return;
} }
// copy = Natom length vector of per-atom values
// use atom ID to insert each atom's values into copy
// MPI_Allreduce with MPI_SUM to merge into data, ordered by atom ID
if (type == 0) { if (type == 0) {
int *vector = nullptr; int *vector = nullptr;
int **array = nullptr; int **array = nullptr;
@ -5490,7 +5467,8 @@ int lammps_neighlist_num_elements(void *handle, int idx) {
* \param[out] numneigh number of neighbors of atom iatom or 0 * \param[out] numneigh number of neighbors of atom iatom or 0
* \param[out] neighbors pointer to array of neighbor atom local indices or NULL */ * \param[out] neighbors pointer to array of neighbor atom local indices or NULL */
void lammps_neighlist_element_neighbors(void *handle, int idx, int element, int *iatom, int *numneigh, int **neighbors) { void lammps_neighlist_element_neighbors(void *handle, int idx, int element, int *iatom,
int *numneigh, int **neighbors) {
auto lmp = (LAMMPS *) handle; auto lmp = (LAMMPS *) handle;
Neighbor * neighbor = lmp->neighbor; Neighbor * neighbor = lmp->neighbor;
*iatom = -1; *iatom = -1;
@ -5777,9 +5755,7 @@ otherwise 0.
* \param setting string with the name of the specific setting * \param setting string with the name of the specific setting
* \return 1 if available, 0 if not. * \return 1 if available, 0 if not.
*/ */
int lammps_config_accelerator(const char *package, int lammps_config_accelerator(const char *package, const char *category, const char *setting)
const char *category,
const char *setting)
{ {
return Info::has_accelerator_feature(package,category,setting) ? 1 : 0; return Info::has_accelerator_feature(package,category,setting) ? 1 : 0;
} }
@ -5901,8 +5877,7 @@ int lammps_style_count(void *handle, const char *category) {
* \param buf_size size of the provided string buffer * \param buf_size size of the provided string buffer
* \return 1 if successful, otherwise 0 * \return 1 if successful, otherwise 0
*/ */
int lammps_style_name(void *handle, const char *category, int idx, int lammps_style_name(void *handle, const char *category, int idx, char *buffer, int buf_size) {
char *buffer, int buf_size) {
auto lmp = (LAMMPS *) handle; auto lmp = (LAMMPS *) handle;
Info info(lmp); Info info(lmp);
auto styles = info.get_available_styles(category); auto styles = info.get_available_styles(category);

View File

@ -521,8 +521,10 @@ void PairHybrid::coeff(int narg, char **arg)
int none = 0; int none = 0;
if (m == nstyles) { if (m == nstyles) {
if (strcmp(arg[2],"none") == 0) none = 1; if (strcmp(arg[2],"none") == 0)
else error->all(FLERR,"Pair coeff for hybrid has invalid style: {}", arg[2]); none = 1;
else
error->all(FLERR,"Expected hybrid sub-style instead of {} in pair_coeff command", arg[2]);
} }
// move 1st/2nd args to 2nd/3rd args // move 1st/2nd args to 2nd/3rd args

View File

@ -59,8 +59,10 @@ void PairHybridOverlay::coeff(int narg, char **arg)
int none = 0; int none = 0;
if (m == nstyles) { if (m == nstyles) {
if (strcmp(arg[2],"none") == 0) none = 1; if (strcmp(arg[2],"none") == 0)
else error->all(FLERR,"Pair coeff for hybrid has invalid style: {}", arg[2]); none = 1;
else
error->all(FLERR,"Expected hybrid sub-style instead of {} in pair_coeff command", arg[2]);
} }
// move 1st/2nd args to 2nd/3rd args // move 1st/2nd args to 2nd/3rd args

View File

@ -516,7 +516,7 @@ void PairHybridScaled::coeff(int narg, char **arg)
if (strcmp(arg[2], "none") == 0) if (strcmp(arg[2], "none") == 0)
none = 1; none = 1;
else else
error->all(FLERR, "Pair coeff for hybrid has invalid style: {}", arg[2]); error->all(FLERR, "Expected hybrid sub-style instead of {} in pair_coeff command", arg[2]);
} }
// move 1st/2nd args to 2nd/3rd args // move 1st/2nd args to 2nd/3rd args

View File

@ -1657,17 +1657,19 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
if (!compute->array_flag) if (!compute->array_flag)
print_var_error(FLERR,"Mismatched compute in variable formula",ivar); print_var_error(FLERR,"Mismatched compute in variable formula",ivar);
if (compute->size_array_rows == 0)
print_var_error(FLERR,"Variable formula compute array is zero length",ivar);
if (index1 > compute->size_array_cols)
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
if (!compute->is_initialized()) if (!compute->is_initialized())
print_var_error(FLERR,"Variable formula compute cannot be invoked before " print_var_error(FLERR,"Variable formula compute cannot be invoked before "
"initialization by a run",ivar); "initialization by a run",ivar);
if (index1 > compute->size_array_cols)
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) {
compute->compute_array(); compute->compute_array();
compute->invoked_flag |= Compute::INVOKED_ARRAY; compute->invoked_flag |= Compute::INVOKED_ARRAY;
} }
// wait until after compute invocation to check size_array_rows
// b/c may be zero until after initial invocation
if (compute->size_array_rows == 0)
print_var_error(FLERR,"Variable formula compute array is zero length",ivar);
auto newtree = new Tree(); auto newtree = new Tree();
newtree->type = VECTORARRAY; newtree->type = VECTORARRAY;