diff --git a/doc/src/compute_property_atom.rst b/doc/src/compute_property_atom.rst index 34ff62944a..2e9619062e 100644 --- a/doc/src/compute_property_atom.rst +++ b/doc/src/compute_property_atom.rst @@ -31,7 +31,7 @@ Syntax corner2x, corner2y, corner2z, corner3x, corner3y, corner3z, i_name, d_name, i2_name[I], d2_name[I], - vfrac, s0, spin, eradius, ervel, erforce, + vfrac, s0, espin, eradius, ervel, erforce, rho, drho, e, de, cv, buckling, .. parsed-literal:: @@ -76,7 +76,7 @@ Syntax .. parsed-literal:: EFF and AWPMD package per-atom properties: - spin = electron spin + espin = electron spin eradius = electron radius ervel = electron radial velocity erforce = electron radial force @@ -167,6 +167,10 @@ triangular particles and define the corner points of each triangle. In addition, the various per-atom quantities listed above for specific packages are only accessible by this command. +.. versionchanged:: TBD + + The *espin* property was previously called *spin*. + Output info """"""""""" diff --git a/doc/src/read_data.rst b/doc/src/read_data.rst index 853d86785e..bcde47e970 100644 --- a/doc/src/read_data.rst +++ b/doc/src/read_data.rst @@ -631,7 +631,7 @@ of analysis. * - edpd - atom-ID atom-type edpd_temp edpd_cv x y z * - electron - - atom-ID atom-type q spin eradius x y z + - atom-ID atom-type q espin eradius x y z * - ellipsoid - atom-ID atom-type ellipsoidflag density x y z * - full @@ -663,7 +663,7 @@ of analysis. * - tri - atom-ID molecule-ID atom-type triangleflag density x y z * - wavepacket - - atom-ID atom-type charge spin eradius etag cs_re cs_im x y z + - atom-ID atom-type charge espin eradius etag cs_re cs_im x y z * - hybrid - atom-ID atom-type x y z sub-style1 sub-style2 ... @@ -680,11 +680,12 @@ The per-atom values have these meanings and units, listed alphabetically: * cv = heat capacity (need units) for SPH particles * density = density of particle (mass/distance\^3 or mass/distance\^2 or mass/distance units, depending on dimensionality of particle) * diameter = diameter of spherical atom (distance units) -* esph = energy (need units) for SPH particles * edpd_temp = temperature for eDPD particles (temperature units) * edpd_cv = volumetric heat capacity for eDPD particles (energy/temperature/volume units) * ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles * eradius = electron radius (or fixed-core radius) +* esph = energy (need units) for SPH particles +* espin = electron spin (+1/-1), 0 = nuclei, 2 = fixed-core, 3 = pseudo-cores (i.e. ECP) * etag = integer ID of electron that each wave packet belongs to * kradius = kernel radius for SMD particles (distance units) * lineflag = 1 for line segment particles, 0 for point or spherical particles @@ -695,7 +696,6 @@ The per-atom values have these meanings and units, listed alphabetically: * mux,muy,muz = components of dipole moment of atom (dipole units) * q = charge on atom (charge units) * rho = density (need units) for SPH particles -* spin = electron spin (+1/-1), 0 = nuclei, 2 = fixed-core, 3 = pseudo-cores (i.e. ECP) * sp = magnitude of magnetic spin of atom (Bohr magnetons) * spx,spy,spz = components of magnetic spin of atom (unit vector) * template-atom = which atom within a template molecule the atom is diff --git a/doc/src/set.rst b/doc/src/set.rst index 5bc2cfb957..3d970d7044 100644 --- a/doc/src/set.rst +++ b/doc/src/set.rst @@ -15,10 +15,11 @@ Syntax * one or more keyword/value pairs may be appended * keyword = *type* or *type/fraction* or *type/ratio* or *type/subset* or *mol* or *x* or *y* or *z* or *vx* or *vy* or *vz* or *charge* or - *dipole* or *dipole/random* or *quat* or *spin* or *spin/random* or - *quat* or *quat/random* or *diameter* or *shape* or - *length* or *tri* or *theta* or *theta/random* or *angmom* or - *omega* or *mass* or *density* or *density/disc* or + *dipole* or *dipole/random* or *quat* or *spin/atom* or *spin/atom/random* or + *spin/electron* or *radius/electron* or + *quat* or *quat/random* or *diameter* or *shape* or *length* or *tri* or + *theta* or *theta/random* or *angmom* or *omega* or + *mass* or *density* or *density/disc* or *volume* or *image* or *bond* or *angle* or *dihedral* or *improper* or *sph/e* or *sph/cv* or *sph/rho* or *smd/contact/radius* or *smd/mass/density* or *dpd/theta* or @@ -55,13 +56,17 @@ Syntax *dipole/random* value = seed Dlen seed = random # seed (positive integer) for dipole moment orientations Dlen = magnitude of dipole moment (dipole units) - *spin* values = g x y z + *spin/atom* values = g x y z g = magnitude of magnetic spin vector (in Bohr magneton's unit) x,y,z = orientation of magnetic spin vector any of x,y,z can be an atom-style variable (see below) - *spin/random* value = seed Dlen + *spin/atom/random* value = seed Dlen seed = random # seed (positive integer) for magnetic spin orientations Dlen = magnitude of magnetic spin vector (in Bohr magneton's unit) + *radius/electron* values = eradius + eradius = electron radius (or fixed-core radius) (distance units) + *spin/electron* value = espin + espin = electron spin (+1/-1), 0 = nuclei, 2 = fixed-core, 3 = pseudo-cores (i.e. ECP) *quat* values = a b c theta a,b,c = unit vector to rotate particle around via right-hand rule theta = rotation angle (degrees) @@ -277,14 +282,28 @@ the orientation of a particular atom is the same, regardless of how many processors are being used. This keyword does not allow use of an atom-style variable. -Keyword *spin* uses the specified g value to set the magnitude of the +.. versionchanged:: TBD + +Keyword *spin/atom* uses the specified g value to set the magnitude of the magnetic spin vectors, and the x,y,z values as components of a vector to set as the orientation of the magnetic spin vectors of the selected -atoms. +atoms. This keyword was previously called *spin*. -Keyword *spin/random* randomizes the orientation of the magnetic spin +.. versionchanged:: TBD + +Keyword *spin/atom/random* randomizes the orientation of the magnetic spin vectors for the selected atoms and sets the magnitude of each to the -specified *Dlen* value. +specified *Dlen* value. This keyword was previously called *spin/random*. + +.. versionadded:: TBD + +Keyword *radius/electron* uses the specified value to set the radius of +electrons or fixed cores. + +.. versionadded:: TBD + +Keyword *spin/electron* sets the spin of an electron (+/- 1) or indicates +nuclei (=0), fixed-cores (=2), or pseudo-cores (= 3). Keyword *quat* uses the specified values to create a quaternion (4-vector) that represents the orientation of the selected atoms. The diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 9b0ea99369..f9b267863a 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -975,6 +975,7 @@ Eshelby eskm Espanol esph +espin estretch esu esub diff --git a/src/AWPMD/atom_vec_wavepacket.cpp b/src/AWPMD/atom_vec_wavepacket.cpp index 59a503571e..b4950e2ef0 100644 --- a/src/AWPMD/atom_vec_wavepacket.cpp +++ b/src/AWPMD/atom_vec_wavepacket.cpp @@ -39,18 +39,18 @@ AtomVecWavepacket::AtomVecWavepacket(LAMMPS *lmp) : AtomVec(lmp) // order of fields in a string does not matter // except: fields_data_atom & fields_data_vel must match data file - fields_grow = {"q", "spin", "eradius", "ervel", "erforce", + fields_grow = {"q", "espin", "eradius", "ervel", "erforce", "cs", "csforce", "vforce", "ervelforce", "etag"}; - fields_copy = {"q", "spin", "eradius", "ervel", "cs", "etag"}; + fields_copy = {"q", "espin", "eradius", "ervel", "cs", "etag"}; fields_comm = {"eradius"}; fields_comm_vel = {"eradius", "ervel", "cs"}; fields_reverse = {"erforce", "ervelforce", "vforce", "csforce"}; - fields_border = {"q", "spin", "eradius", "etag"}; - fields_border_vel = {"q", "spin", "eradius", "etag", "ervel", "cs"}; - fields_exchange = {"q", "spin", "eradius", "ervel", "etag", "cs"}; - fields_restart = {"q", "spin", "eradius", "ervel", "etag", "cs"}; - fields_create = {"q", "spin", "eradius", "ervel", "etag", "cs"}; - fields_data_atom = {"id", "type", "q", "spin", "eradius", "etag", "cs", "x"}; + fields_border = {"q", "espin", "eradius", "etag"}; + fields_border_vel = {"q", "espin", "eradius", "etag", "ervel", "cs"}; + fields_exchange = {"q", "espin", "eradius", "ervel", "etag", "cs"}; + fields_restart = {"q", "espin", "eradius", "ervel", "etag", "cs"}; + fields_create = {"q", "espin", "eradius", "ervel", "etag", "cs"}; + fields_data_atom = {"id", "type", "q", "espin", "eradius", "etag", "cs", "x"}; fields_data_vel = {"id", "v", "ervel"}; setup_fields(); @@ -107,7 +107,8 @@ void AtomVecWavepacket::data_atom_post(int ilocal) int AtomVecWavepacket::property_atom(const std::string &name) { - if (name == "spin") return 0; + if (name == "espin") return 0; + if (name == "spin") return 0; // backward compatibility if (name == "eradius") return 1; if (name == "ervel") return 2; if (name == "erforce") return 3; diff --git a/src/EFF/atom_vec_electron.cpp b/src/EFF/atom_vec_electron.cpp index 5d600b5037..e456c1916c 100644 --- a/src/EFF/atom_vec_electron.cpp +++ b/src/EFF/atom_vec_electron.cpp @@ -53,17 +53,17 @@ AtomVecElectron::AtomVecElectron(LAMMPS *lmp) : AtomVec(lmp) // order of fields in a string does not matter // except: fields_data_atom & fields_data_vel must match data file - fields_grow = {"q", "spin", "eradius", "ervel", "erforce"}; - fields_copy = {"q", "spin", "eradius", "ervel"}; + fields_grow = {"q", "espin", "eradius", "ervel", "erforce"}; + fields_copy = {"q", "espin", "eradius", "ervel"}; fields_comm = {"eradius"}; fields_comm_vel = {"eradius"}; fields_reverse = {"erforce"}; - fields_border = {"q", "spin", "eradius"}; - fields_border_vel = {"q", "spin", "eradius"}; - fields_exchange = {"q", "spin", "eradius", "ervel"}; - fields_restart = {"q", "spin", "eradius", "ervel"}; - fields_create = {"q", "spin", "eradius", "ervel"}; - fields_data_atom = {"id", "type", "q", "spin", "eradius", "x"}; + fields_border = {"q", "espin", "eradius"}; + fields_border_vel = {"q", "espin", "eradius"}; + fields_exchange = {"q", "espin", "eradius", "ervel"}; + fields_restart = {"q", "espin", "eradius", "ervel"}; + fields_create = {"q", "espin", "eradius", "ervel"}; + fields_data_atom = {"id", "type", "q", "espin", "eradius", "x"}; fields_data_vel = {"id", "v", "ervel"}; setup_fields(); @@ -119,7 +119,8 @@ void AtomVecElectron::data_atom_post(int ilocal) int AtomVecElectron::property_atom(const std::string &name) { - if (name == "spin") return 0; + if (name == "espin") return 0; + if (name == "spin") return 0; // backward compatibility if (name == "eradius") return 1; if (name == "ervel") return 2; if (name == "erforce") return 3; diff --git a/src/atom.cpp b/src/atom.cpp index 085b76def5..500dc4ff1d 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -480,7 +480,7 @@ void Atom::peratom_create() // EFF package - add_peratom("spin",&spin,INT,0); + add_peratom("espin",&spin,INT,0); add_peratom("eradius",&eradius,DOUBLE,0); add_peratom("ervel",&ervel,DOUBLE,0); add_peratom("erforce",&erforce,DOUBLE,0,1); // set per-thread flag @@ -760,6 +760,21 @@ void Atom::setup() if (sortfreq > 0) setup_sort_bins(); } +/* ---------------------------------------------------------------------- */ + +std::string Atom::get_style() +{ + std::string retval = atom_style; + if (retval == "hybrid") { + auto avec_hybrid = dynamic_cast(avec); + for (int i = 0; i < avec_hybrid->nstyles; i++) { + retval += ' '; + retval += avec_hybrid->keywords[i]; + } + } + return retval; +} + /* ---------------------------------------------------------------------- return ptr to AtomVec class if matches style or to matching hybrid sub-class return nullptr if no match @@ -2691,7 +2706,8 @@ void *Atom::extract(const char *name) // EFF and AWPMD packages - if (strcmp(name,"spin") == 0) return (void *) spin; + if (strcmp(name,"espin") == 0) return (void *) spin; + if (strcmp(name,"spin") == 0) return (void *) spin; // backward compatibility if (strcmp(name,"eradius") == 0) return (void *) eradius; if (strcmp(name,"ervel") == 0) return (void *) ervel; if (strcmp(name,"erforce") == 0) return (void *) erforce; @@ -2815,7 +2831,8 @@ int Atom::extract_datatype(const char *name) if (strcmp(name,"s0") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"x0") == 0) return LAMMPS_DOUBLE_2D; - if (strcmp(name,"spin") == 0) return LAMMPS_INT; + if (strcmp(name,"espin") == 0) return LAMMPS_INT; + if (strcmp(name,"spin") == 0) return LAMMPS_INT; // backwards compatibility if (strcmp(name,"eradius") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"ervel") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"erforce") == 0) return LAMMPS_DOUBLE; diff --git a/src/atom.h b/src/atom.h index 399ad5023c..837711d439 100644 --- a/src/atom.h +++ b/src/atom.h @@ -311,6 +311,7 @@ class Atom : protected Pointers { void init(); void setup(); + std::string get_style(); AtomVec *style_match(const char *); void modify_params(int, char **); void tag_check(); diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index 606da288de..4d55549d99 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -39,7 +39,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg), index(nullptr), colindex(nullptr), pack_choice(nullptr) { - if (narg < 4) error->all(FLERR,"Illegal compute property/atom command"); + if (narg < 4) utils::missing_cmd_args(FLERR, "compute property/atom", error); peratom_flag = 1; nvalues = narg - 3; @@ -52,6 +52,10 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : pack_choice = new FnPtrPack[nvalues]; index = new int[nvalues]; colindex = new int[nvalues]; + avec_ellipsoid = dynamic_cast(atom->style_match("ellipsoid")); + avec_body = dynamic_cast(atom->style_match("body")); + avec_line = dynamic_cast(atom->style_match("line")); + avec_tri = dynamic_cast(atom->style_match("tri")); int i; for (int iarg = 3; iarg < narg; iarg++) { @@ -61,8 +65,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : pack_choice[i] = &ComputePropertyAtom::pack_id; } else if (strcmp(arg[iarg],"mol") == 0) { if (!atom->molecule_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_molecule; } else if (strcmp(arg[iarg],"proc") == 0) { pack_choice[i] = &ComputePropertyAtom::pack_proc; @@ -123,217 +126,204 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[iarg],"q") == 0) { if (!atom->q_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_q; } else if (strcmp(arg[iarg],"mux") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_mux; } else if (strcmp(arg[iarg],"muy") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_muy; } else if (strcmp(arg[iarg],"muz") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_muz; } else if (strcmp(arg[iarg],"mu") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_mu; // pack magnetic variables } else if (strcmp(arg[iarg],"spx") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_spx; } else if (strcmp(arg[iarg],"spy") == 0) { + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_spy; } else if (strcmp(arg[iarg],"spz") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_spz; } else if (strcmp(arg[iarg],"sp") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_sp; } else if (strcmp(arg[iarg],"fmx") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_fmx; } else if (strcmp(arg[iarg],"fmy") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_fmy; } else if (strcmp(arg[iarg],"fmz") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_fmz; // bond count } else if (strcmp(arg[iarg],"nbonds") == 0) { if (!atom->molecule_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_nbonds; // finite-size particles } else if (strcmp(arg[iarg],"radius") == 0) { if (!atom->radius_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_radius; } else if (strcmp(arg[iarg],"diameter") == 0) { if (!atom->radius_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_diameter; } else if (strcmp(arg[iarg],"omegax") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_omegax; } else if (strcmp(arg[iarg],"omegay") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_omegay; } else if (strcmp(arg[iarg],"omegaz") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_omegaz; } else if (strcmp(arg[iarg],"angmomx") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_angmomx; } else if (strcmp(arg[iarg],"angmomy") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_angmomy; } else if (strcmp(arg[iarg],"angmomz") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_angmomz; } else if (strcmp(arg[iarg],"shapex") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_ellipsoid) + error->all(FLERR,"Compute property/atom {} requires atom style ellipsoid", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_shapex; } else if (strcmp(arg[iarg],"shapey") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_ellipsoid) + error->all(FLERR,"Compute property/atom {} requires atom style ellipsoid", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_shapey; } else if (strcmp(arg[iarg],"shapez") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_ellipsoid) + error->all(FLERR,"Compute property/atom {} requires atom style ellipsoid", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_shapez; } else if (strcmp(arg[iarg],"quatw") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - avec_body = dynamic_cast( atom->style_match("body")); if (!avec_ellipsoid && !avec_body && !atom->quat_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_quatw; } else if (strcmp(arg[iarg],"quati") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - avec_body = dynamic_cast( atom->style_match("body")); if (!avec_ellipsoid && !avec_body && !atom->quat_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_quati; } else if (strcmp(arg[iarg],"quatj") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - avec_body = dynamic_cast( atom->style_match("body")); if (!avec_ellipsoid && !avec_body && !atom->quat_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_quatj; } else if (strcmp(arg[iarg],"quatk") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - avec_body = dynamic_cast( atom->style_match("body")); if (!avec_ellipsoid && !avec_body && !atom->quat_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_quatk; } else if (strcmp(arg[iarg],"tqx") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_tqx; } else if (strcmp(arg[iarg],"tqy") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_tqy; } else if (strcmp(arg[iarg],"tqz") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_tqz; } else if (strcmp(arg[iarg],"end1x") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end1x; } else if (strcmp(arg[iarg],"end1y") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end1y; } else if (strcmp(arg[iarg],"end1z") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end1z; } else if (strcmp(arg[iarg],"end2x") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end2x; } else if (strcmp(arg[iarg],"end2y") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end2y; } else if (strcmp(arg[iarg],"end2z") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end2z; } else if (strcmp(arg[iarg],"corner1x") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner1x; } else if (strcmp(arg[iarg],"corner1y") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner1y; } else if (strcmp(arg[iarg],"corner1z") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner1z; } else if (strcmp(arg[iarg],"corner2x") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner2x; - } else if (strcmp(arg[iarg],"corner2y") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner2y; } else if (strcmp(arg[iarg],"corner2z") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner2z; } else if (strcmp(arg[iarg],"corner3x") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner3x; } else if (strcmp(arg[iarg],"corner3y") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner3y; } else if (strcmp(arg[iarg],"corner3z") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner3z; - } else if (strcmp(arg[iarg],"nbonds") == 0) { - if (!atom->molecule_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); - pack_choice[i] = &ComputePropertyAtom::pack_nbonds; - // custom per-atom vector or array } else if (utils::strmatch(arg[iarg],"^[id]2?_")) { @@ -386,7 +376,8 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : } else { index[i] = atom->avec->property_atom(arg[iarg]); if (index[i] < 0) - error->all(FLERR,"Invalid keyword in compute property/atom command"); + error->all(FLERR,"Invalid keyword {} for atom style {} in compute property/atom command ", + atom->get_style(), arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_atom_style; } } @@ -398,9 +389,9 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : ComputePropertyAtom::~ComputePropertyAtom() { - delete [] pack_choice; - delete [] index; - delete [] colindex; + delete[] pack_choice; + delete[] index; + delete[] colindex; memory->destroy(vector_atom); memory->destroy(array_atom); } diff --git a/src/info.cpp b/src/info.cpp index dc59bdadee..a93c57780e 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -402,7 +402,7 @@ void Info::command(int narg, char **arg) if (flags & SYSTEM) { fputs("\nSystem information:\n",out); fmt::print(out,"Units = {}\n", update->unit_style); - fmt::print(out,"Atom style = {}\n", atom->atom_style); + fmt::print(out,"Atom style = {}\n", atom->get_style()); fmt::print(out,"Atom map = {}\n", mapstyles[atom->map_style]); if (atom->molecular != Atom::ATOMIC) { const char *msg; diff --git a/src/set.cpp b/src/set.cpp index 2843281d78..80c524f8a4 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -46,9 +46,9 @@ enum{ATOM_SELECT,MOL_SELECT,TYPE_SELECT,GROUP_SELECT,REGION_SELECT}; enum{TYPE,TYPE_FRACTION,TYPE_RATIO,TYPE_SUBSET, MOLECULE,X,Y,Z,VX,VY,VZ,CHARGE,MASS,SHAPE,LENGTH,TRI, - DIPOLE,DIPOLE_RANDOM,SPIN,SPIN_RANDOM,QUAT,QUAT_RANDOM, - THETA,THETA_RANDOM,ANGMOM,OMEGA, - DIAMETER,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER, + DIPOLE,DIPOLE_RANDOM,SPIN_ATOM,SPIN_RANDOM,SPIN_ELECTRON,RADIUS_ELECTRON, + QUAT,QUAT_RANDOM,THETA,THETA_RANDOM,ANGMOM,OMEGA, + DIAMETER,RADIUS_ATOM,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER, SPH_E,SPH_CV,SPH_RHO,EDPD_TEMP,EDPD_CV,CC,SMD_MASS_DENSITY, SMD_CONTACT_RADIUS,DPDTHETA,EPSILON,IVEC,DVEC,IARRAY,DARRAY}; @@ -61,8 +61,8 @@ void Set::command(int narg, char **arg) if (domain->box_exist == 0) error->all(FLERR,"Set command before simulation box is defined"); if (atom->natoms == 0) - error->all(FLERR,"Set command with no atoms existing"); - if (narg < 3) error->all(FLERR,"Illegal set command"); + error->all(FLERR,"Set command on system without atoms"); + if (narg < 4) error->all(FLERR,"Illegal set command: need at least four arguments"); // style and ID info @@ -71,7 +71,7 @@ void Set::command(int narg, char **arg) else if (strcmp(arg[0],"type") == 0) style = TYPE_SELECT; else if (strcmp(arg[0],"group") == 0) style = GROUP_SELECT; else if (strcmp(arg[0],"region") == 0) style = REGION_SELECT; - else error->all(FLERR,"Illegal set command"); + else error->all(FLERR,"Unknown set command style: {}", arg[0]); id = utils::strdup(arg[1]); select = nullptr; @@ -91,125 +91,125 @@ void Set::command(int narg, char **arg) origarg = iarg; if (strcmp(arg[iarg],"type") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set type", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); set(TYPE); iarg += 2; } else if (strcmp(arg[iarg],"type/fraction") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set type/fraction", error); newtype = utils::inumeric(FLERR,arg[iarg+1],false,lmp); fraction = utils::numeric(FLERR,arg[iarg+2],false,lmp); ivalue = utils::inumeric(FLERR,arg[iarg+3],false,lmp); if (newtype <= 0 || newtype > atom->ntypes) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid type value {} in set type/fraction command", newtype); if (fraction < 0.0 || fraction > 1.0) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid fraction value {} in set type/fraction command", fraction); if (ivalue <= 0) - error->all(FLERR,"Invalid random number seed in set command"); + error->all(FLERR,"Invalid random number seed {} in set type/fraction command", ivalue); setrandom(TYPE_FRACTION); iarg += 4; } else if (strcmp(arg[iarg],"type/ratio") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set type/ratio", error); newtype = utils::inumeric(FLERR,arg[iarg+1],false,lmp); fraction = utils::numeric(FLERR,arg[iarg+2],false,lmp); ivalue = utils::inumeric(FLERR,arg[iarg+3],false,lmp); if (newtype <= 0 || newtype > atom->ntypes) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid type value {} in set type/ratio command", newtype); if (fraction < 0.0 || fraction > 1.0) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid fraction value {} in set type/ratio command", fraction); if (ivalue <= 0) - error->all(FLERR,"Invalid random number seed in set command"); + error->all(FLERR,"Invalid random number seed {} in set type/ratio command", ivalue); setrandom(TYPE_RATIO); iarg += 4; } else if (strcmp(arg[iarg],"type/subset") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set type/subset", error); newtype = utils::inumeric(FLERR,arg[iarg+1],false,lmp); nsubset = utils::bnumeric(FLERR,arg[iarg+2],false,lmp); ivalue = utils::inumeric(FLERR,arg[iarg+3],false,lmp); if (newtype <= 0 || newtype > atom->ntypes) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid type value {} in set type/subset command", newtype); if (nsubset < 0) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid subset size {} in set type/subset command", nsubset); if (ivalue <= 0) - error->all(FLERR,"Invalid random number seed in set command"); + error->all(FLERR,"Invalid random number seed {} in set type/subset command", ivalue); setrandom(TYPE_SUBSET); iarg += 4; } else if (strcmp(arg[iarg],"mol") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set mol", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (!atom->molecule_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(MOLECULE); iarg += 2; } else if (strcmp(arg[iarg],"x") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set x", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(X); iarg += 2; } else if (strcmp(arg[iarg],"y") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set y", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(Y); iarg += 2; } else if (strcmp(arg[iarg],"z") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set z", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(Z); iarg += 2; } else if (strcmp(arg[iarg],"vx") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set vx", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(VX); iarg += 2; } else if (strcmp(arg[iarg],"vy") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set vy", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(VY); iarg += 2; } else if (strcmp(arg[iarg],"vz") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set vz", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(VZ); iarg += 2; } else if (strcmp(arg[iarg],"charge") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set charge", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->q_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(CHARGE); iarg += 2; } else if (strcmp(arg[iarg],"mass") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set mass", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->rmass_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(MASS); iarg += 2; } else if (strcmp(arg[iarg],"shape") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set shape", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else xvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -217,30 +217,30 @@ void Set::command(int narg, char **arg) if (utils::strmatch(arg[iarg+3],"^v_")) varparse(arg[iarg+3],3); else zvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (!atom->ellipsoid_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SHAPE); iarg += 4; } else if (strcmp(arg[iarg],"length") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set length", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->line_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(LENGTH); iarg += 2; } else if (strcmp(arg[iarg],"tri") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set tri", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->tri_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(TRI); iarg += 2; } else if (strcmp(arg[iarg],"dipole") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set dipole", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else xvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -248,16 +248,16 @@ void Set::command(int narg, char **arg) if (utils::strmatch(arg[iarg+3],"^v_")) varparse(arg[iarg+3],3); else zvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (!atom->mu_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(DIPOLE); iarg += 4; } else if (strcmp(arg[iarg],"dipole/random") == 0) { - if (iarg+3 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+3 > narg) utils::missing_cmd_args(FLERR, "set dipole/random", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); dvalue = utils::numeric(FLERR,arg[iarg+2],false,lmp); if (!atom->mu_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); if (dvalue <= 0.0) @@ -265,8 +265,10 @@ void Set::command(int narg, char **arg) setrandom(DIPOLE_RANDOM); iarg += 3; - } else if (strcmp(arg[iarg],"spin") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + } else if ((strcmp(arg[iarg],"spin") == 0) || (strcmp(arg[iarg],"spin/atom") == 0)) { + if ((strcmp(arg[iarg],"spin") == 0) && (comm->me == 0)) + error->warning(FLERR, "Set attribute spin is deprecated. Please use spin/atom instead."); + if (iarg+5 > narg) utils::missing_cmd_args(FLERR, "set spin/atom", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -275,26 +277,52 @@ void Set::command(int narg, char **arg) else yvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (utils::strmatch(arg[iarg+4],"^v_")) varparse(arg[iarg+4],4); else zvalue = utils::numeric(FLERR,arg[iarg+4],false,lmp); + if ((xvalue == 0.0) && (yvalue == 0.0) && (zvalue == 0.0)) + error->all(FLERR,"At least one spin vector component must be non-zero"); if (!atom->sp_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); - set(SPIN); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); + if (dvalue <= 0.0) + error->all(FLERR,"Invalid spin magnitude {} in set {} command", dvalue, arg[iarg]); + set(SPIN_ATOM); iarg += 5; - } else if (strcmp(arg[iarg],"spin/random") == 0) { - if (iarg+3 > narg) error->all(FLERR,"Illegal set command"); + } else if ((strcmp(arg[iarg],"spin/random") == 0) || + (strcmp(arg[iarg],"spin/atom/random") == 0)) { + if (iarg+3 > narg) utils::missing_cmd_args(FLERR, "set spin/atom/random", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); dvalue = utils::numeric(FLERR,arg[iarg+2],false,lmp); + if ((strcmp(arg[iarg],"spin/random") == 0) && (comm->me == 0)) + error->warning(FLERR, "Set attribute spin/random is deprecated. " + "Please use spin/atom/random instead."); if (!atom->sp_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0) - error->all(FLERR,"Invalid random number seed in set command"); + error->all(FLERR,"Invalid random number seed {} in set {} command", ivalue, arg[iarg]); if (dvalue <= 0.0) - error->all(FLERR,"Invalid dipole length in set command"); + error->all(FLERR,"Invalid spin magnitude {} in set {} command", dvalue, arg[iarg]); setrandom(SPIN_RANDOM); iarg += 3; + } else if (strcmp(arg[iarg],"radius/electron") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set radius/electron", error); + if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); + else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); + if (!atom->eradius_flag) + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); + set(RADIUS_ELECTRON); + iarg += 2; + + } else if (strcmp(arg[iarg],"spin/electron") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set spin/electron", error); + if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); + else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); + if (!atom->spin_flag) + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); + set(SPIN_ELECTRON); + iarg += 2; + } else if (strcmp(arg[iarg],"quat") == 0) { - if (iarg+5 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+5 > narg) utils::missing_cmd_args(FLERR, "set quat", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else xvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -304,41 +332,41 @@ void Set::command(int narg, char **arg) if (utils::strmatch(arg[iarg+4],"^v_")) varparse(arg[iarg+4],4); else wvalue = utils::numeric(FLERR,arg[iarg+4],false,lmp); if (!atom->ellipsoid_flag && !atom->tri_flag && !atom->body_flag && !atom->quat_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(QUAT); iarg += 5; } else if (strcmp(arg[iarg],"quat/random") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set quat/random", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (!atom->ellipsoid_flag && !atom->tri_flag && !atom->body_flag && !atom->quat_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); setrandom(QUAT_RANDOM); iarg += 2; } else if (strcmp(arg[iarg],"theta") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set theta", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = DEG2RAD * utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->line_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(THETA); iarg += 2; } else if (strcmp(arg[iarg],"theta/random") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set theta/random", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (!atom->line_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); set(THETA_RANDOM); iarg += 2; } else if (strcmp(arg[iarg],"angmom") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set angmom", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else xvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -346,12 +374,12 @@ void Set::command(int narg, char **arg) if (utils::strmatch(arg[iarg+3],"^v_")) varparse(arg[iarg+3],3); else zvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (!atom->angmom_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(ANGMOM); iarg += 4; } else if (strcmp(arg[iarg],"omega") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set omega", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else xvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -359,26 +387,35 @@ void Set::command(int narg, char **arg) if (utils::strmatch(arg[iarg+3],"^v_")) varparse(arg[iarg+3],3); else zvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (!atom->omega_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(OMEGA); iarg += 4; - } else if (strcmp(arg[iarg],"diameter") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + } else if (strcmp(arg[iarg],"radius/atom") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set radius/atom", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->radius_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); + set(RADIUS_ATOM); + iarg += 2; + + } else if (strcmp(arg[iarg],"diameter") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set diameter", error); + if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); + else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); + if (!atom->radius_flag) + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(DIAMETER); iarg += 2; } else if (strcmp(arg[iarg],"density") == 0 || (strcmp(arg[iarg],"density/disc") == 0)) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set density", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->rmass_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (dvalue <= 0.0) error->all(FLERR,"Invalid density in set command"); discflag = 0; if (strcmp(arg[iarg],"density/disc") == 0) { @@ -390,17 +427,17 @@ void Set::command(int narg, char **arg) iarg += 2; } else if (strcmp(arg[iarg],"volume") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set volume", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->vfrac_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (dvalue <= 0.0) error->all(FLERR,"Invalid volume in set command"); set(VOLUME); iarg += 2; } else if (strcmp(arg[iarg],"image") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set image", error); ximageflag = yimageflag = zimageflag = 0; if (strcmp(arg[iarg+1],"NULL") != 0) { ximageflag = 1; @@ -430,74 +467,74 @@ void Set::command(int narg, char **arg) iarg += 4; } else if (strcmp(arg[iarg],"bond") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set bond", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (atom->avec->bonds_allow == 0) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0 || ivalue > atom->nbondtypes) error->all(FLERR,"Invalid value in set command"); topology(BOND); iarg += 2; } else if (strcmp(arg[iarg],"angle") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set angle", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (atom->avec->angles_allow == 0) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0 || ivalue > atom->nangletypes) error->all(FLERR,"Invalid value in set command"); topology(ANGLE); iarg += 2; } else if (strcmp(arg[iarg],"dihedral") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set dihedral", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (atom->avec->dihedrals_allow == 0) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0 || ivalue > atom->ndihedraltypes) error->all(FLERR,"Invalid value in set command"); topology(DIHEDRAL); iarg += 2; } else if (strcmp(arg[iarg],"improper") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set improper", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (atom->avec->impropers_allow == 0) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0 || ivalue > atom->nimpropertypes) error->all(FLERR,"Invalid value in set command"); topology(IMPROPER); iarg += 2; } else if (strcmp(arg[iarg],"sph/e") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set sph/e", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->esph_flag) - error->all(FLERR,"Cannot set meso/e for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SPH_E); iarg += 2; } else if (strcmp(arg[iarg],"sph/cv") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set sph/cv", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->cv_flag) - error->all(FLERR,"Cannot set meso/cv for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SPH_CV); iarg += 2; } else if (strcmp(arg[iarg],"sph/rho") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set sph/rho", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->rho_flag) - error->all(FLERR,"Cannot set meso/rho for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SPH_RHO); iarg += 2; } else if (strcmp(arg[iarg],"edpd/temp") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set edpd/temp", error); if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; else if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else { @@ -505,12 +542,12 @@ void Set::command(int narg, char **arg) if (dvalue < 0.0) error->all(FLERR,"Illegal set command"); } if (!atom->edpd_flag) - error->all(FLERR,"Cannot set edpd/temp for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(EDPD_TEMP); iarg += 2; } else if (strcmp(arg[iarg],"edpd/cv") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set edpd/cv", error); if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; else if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else { @@ -518,12 +555,12 @@ void Set::command(int narg, char **arg) if (dvalue < 0.0) error->all(FLERR,"Illegal set command"); } if (!atom->edpd_flag) - error->all(FLERR,"Cannot set edpd/cv for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(EDPD_CV); iarg += 2; } else if (strcmp(arg[iarg],"cc") == 0) { - if (iarg+3 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+3 > narg) utils::missing_cmd_args(FLERR, "set cc", error); if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; else if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else { @@ -532,31 +569,30 @@ void Set::command(int narg, char **arg) if (cc_index < 1) error->all(FLERR,"Illegal set command"); } if (!atom->tdpd_flag) - error->all(FLERR,"Cannot set cc for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(CC); iarg += 3; } else if (strcmp(arg[iarg],"smd/mass/density") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set smd/mass/density", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->smd_flag) - error->all(FLERR,"Cannot set smd/mass/density for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SMD_MASS_DENSITY); iarg += 2; } else if (strcmp(arg[iarg],"smd/contact/radius") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set smd/contact/radius", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->smd_flag) - error->all(FLERR,"Cannot set smd/contact/radius " - "for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SMD_CONTACT_RADIUS); iarg += 2; } else if (strcmp(arg[iarg],"dpd/theta") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set dpd/theta", error); if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; else if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else { @@ -564,12 +600,12 @@ void Set::command(int narg, char **arg) if (dvalue < 0.0) error->all(FLERR,"Illegal set command"); } if (!atom->dpd_flag) - error->all(FLERR,"Cannot set dpd/theta for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(DPDTHETA); iarg += 2; } else if (strcmp(arg[iarg],"epsilon") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set epsilon", error); if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; else if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else { @@ -577,7 +613,7 @@ void Set::command(int narg, char **arg) if (dvalue < 0.0) error->all(FLERR,"Illegal set command"); } if (!atom->dielectric_flag) - error->all(FLERR,"Cannot set epsilon for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(EPSILON); iarg += 2; @@ -588,16 +624,17 @@ void Set::command(int narg, char **arg) int flag,cols; ArgInfo argi(arg[iarg],ArgInfo::DNAME|ArgInfo::INAME); const char *pname = argi.get_name(); - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set", error); index_custom = atom->find_custom(argi.get_name(),flag,cols); - if (index_custom < 0) error->all(FLERR,"Custom property {} does not exist",pname); + if (index_custom < 0) + error->all(FLERR,"Set keyword or custom property {} does not exist",pname); switch (argi.get_type()) { case ArgInfo::INAME: if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - if (flag != 0) error->all(FLERR,"Custom property {} is not integer",pname); + if (flag != 0) error->all(FLERR,"Set command custom property {} is not integer",pname); if (argi.get_dim() == 0) { if (cols > 0) @@ -621,14 +658,15 @@ void Set::command(int narg, char **arg) if (argi.get_dim() == 0) { if (cols > 0) - error->all(FLERR,"Set command custom floating-point property is not a vector"); + error->all(FLERR,"Set command custom double property {} is not a vector",pname); set(DVEC); } else if (argi.get_dim() == 1) { if (cols == 0) - error->all(FLERR,"Set command custom floating-point property is not an array"); + error->all(FLERR,"Set command custom double property {} is not an array",pname); icol_custom = argi.get_index1(); if (icol_custom <= 0 || icol_custom > cols) - error->all(FLERR,"Set command per-atom custom integer array is accessed out-of-range"); + error->all(FLERR,"Set command per-atom custom double array {} is " + "accessed out-of-range",pname); set(DARRAY); } else error->all(FLERR,"Illegal set command"); break; @@ -657,8 +695,8 @@ void Set::command(int narg, char **arg) // free local memory - delete [] id; - delete [] select; + delete[] id; + delete[] select; } /* ---------------------------------------------------------------------- @@ -668,7 +706,7 @@ void Set::command(int narg, char **arg) void Set::selection(int n) { - delete [] select; + delete[] select; select = new int[n]; int nlo,nhi; @@ -704,7 +742,7 @@ void Set::selection(int n) } else if (style == GROUP_SELECT) { int igroup = group->find(id); - if (igroup == -1) error->all(FLERR,"Could not find set group ID"); + if (igroup == -1) error->all(FLERR,"Could not find set group ID {}", id); int groupbit = group->bitmask[igroup]; int *mask = atom->mask; @@ -937,7 +975,9 @@ void Set::set(int keyword) // set magnetic moments - else if (keyword == SPIN) { + else if (keyword == SPIN_ATOM) { + if (dvalue < 0.0) + error->one(FLERR,"Incorrect value for atomic spin magnitude: {}", dvalue); double **sp = atom->sp; double inorm = 1.0/sqrt(xvalue*xvalue+yvalue*yvalue+zvalue*zvalue); sp[i][0] = inorm*xvalue; @@ -946,6 +986,23 @@ void Set::set(int keyword) sp[i][3] = dvalue; } + // set electron radius + + else if (keyword == RADIUS_ELECTRON) { + atom->eradius[i] = dvalue; + if (dvalue < 0.0) + error->one(FLERR,"Incorrect value for electron radius: {}", dvalue); + } + + // set electron spin + + else if (keyword == SPIN_ELECTRON) { + if ((dvalue == -1) || (dvalue == 1) || (dvalue == 0) || (dvalue == 2) || (dvalue == 3)) + atom->spin[i] = (int)dvalue; + else + error->one(FLERR,"Incorrect value for electron spin: {}", dvalue); + } + // set quaternion orientation of ellipsoid or tri or body particle or sphere/bpm // enforce quat rotation vector in z dir for 2d systems @@ -1457,9 +1514,9 @@ void Set::varparse(const char *name, int m) int ivar = input->variable->find(name+2); if (ivar < 0) - error->all(FLERR,"Variable name for set command does not exist"); + error->all(FLERR,"Variable name {} for set command does not exist", name); if (!input->variable->atomstyle(ivar)) - error->all(FLERR,"Variable for set command is invalid style"); + error->all(FLERR,"Variable {} for set command is invalid style", name); if (m == 1) { varflag1 = 1; ivar1 = ivar; diff --git a/unittest/commands/CMakeLists.txt b/unittest/commands/CMakeLists.txt index deeee00f71..297bd11054 100644 --- a/unittest/commands/CMakeLists.txt +++ b/unittest/commands/CMakeLists.txt @@ -29,6 +29,10 @@ add_executable(test_delete_atoms test_delete_atoms.cpp) target_link_libraries(test_delete_atoms PRIVATE lammps GTest::GMock) add_test(NAME DeleteAtoms COMMAND test_delete_atoms) +add_executable(test_set_property test_set_property.cpp) +target_link_libraries(test_set_property PRIVATE lammps GTest::GMock) +add_test(NAME SetProperty COMMAND test_set_property) + add_executable(test_variables test_variables.cpp) target_link_libraries(test_variables PRIVATE lammps GTest::GMock) add_test(NAME Variables COMMAND test_variables) diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index 83acab08d4..95164d4a09 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -26,8 +26,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { #define STRINGIFY(val) XSTR(val) @@ -296,7 +294,6 @@ TEST_F(ComputeGlobalTest, Reduction) EXPECT_DOUBLE_EQ(rep[2], 26); EXPECT_DOUBLE_EQ(rep[3], max[0]); } - } // namespace LAMMPS_NS int main(int argc, char **argv) @@ -304,12 +301,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_delete_atoms.cpp b/unittest/commands/test_delete_atoms.cpp index 20d546e69e..2a7cab4718 100644 --- a/unittest/commands/test_delete_atoms.cpp +++ b/unittest/commands/test_delete_atoms.cpp @@ -31,9 +31,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::MathConst::MY_PI; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { using ::testing::ContainsRegex; using ::testing::ExitedWithCode; @@ -164,12 +161,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index 1918f67cbf..8247675b82 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -316,12 +316,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_kim_commands.cpp b/unittest/commands/test_kim_commands.cpp index 2d9c1cd7d4..1bb070ad6c 100644 --- a/unittest/commands/test_kim_commands.cpp +++ b/unittest/commands/test_kim_commands.cpp @@ -683,12 +683,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_lattice_region.cpp b/unittest/commands/test_lattice_region.cpp index a1ac9bd675..257fe6a596 100644 --- a/unittest/commands/test_lattice_region.cpp +++ b/unittest/commands/test_lattice_region.cpp @@ -32,8 +32,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { using ::testing::ContainsRegex; using ::testing::ExitedWithCode; @@ -634,12 +632,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_regions.cpp b/unittest/commands/test_regions.cpp index 4c70385918..2ced0c45f5 100644 --- a/unittest/commands/test_regions.cpp +++ b/unittest/commands/test_regions.cpp @@ -30,8 +30,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { using ::testing::ExitedWithCode; using ::testing::StrEq; @@ -279,12 +277,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_reset_ids.cpp b/unittest/commands/test_reset_ids.cpp index 3d577ad24d..cd311616aa 100644 --- a/unittest/commands/test_reset_ids.cpp +++ b/unittest/commands/test_reset_ids.cpp @@ -29,8 +29,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { #define GETIDX(i) lmp->atom->map(i) @@ -677,7 +675,6 @@ TEST_F(ResetMolIDsTest, FailOnlyMolecular) END_HIDE_OUTPUT(); TEST_FAILURE(".*ERROR: Can only use reset_mol_ids.*", command("reset_mol_ids all");); } - } // namespace LAMMPS_NS int main(int argc, char **argv) @@ -685,12 +682,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp new file mode 100644 index 0000000000..f482463060 --- /dev/null +++ b/unittest/commands/test_set_property.cpp @@ -0,0 +1,433 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "lammps.h" + +#include "atom.h" +#include "compute.h" +#include "domain.h" +#include "math_const.h" +#include "modify.h" + +#include "../testing/core.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +// whether to print verbose output (i.e. not capturing LAMMPS screen output). +bool verbose = false; + +using ::testing::ContainsRegex; +using ::testing::ExitedWithCode; +using ::testing::StrEq; + +namespace LAMMPS_NS { +class SetTest : public LAMMPSTest { +protected: + Atom *atom; + Domain *domain; + void SetUp() override + { + testbinary = "SetTest"; + args = {"-log", "none", "-echo", "screen", "-nocite", "-v", "num", "1"}; + LAMMPSTest::SetUp(); + atom = lmp->atom; + domain = lmp->domain; + } + + void TearDown() override { LAMMPSTest::TearDown(); } + + void atomic_system(const std::string &atom_style, const std::string units = "real") + { + BEGIN_HIDE_OUTPUT(); + command("atom_style " + atom_style); + command("atom_modify map array"); + command("units " + units); + command("lattice sc 1.0 origin 0.125 0.125 0.125"); + command("region box block 0 2 0 2 0 2"); + command("create_box 8 box"); + command("create_atoms 1 box"); + command("mass * 1.0"); + command("region left block 0.0 1.0 INF INF INF INF"); + command("region right block 1.0 2.0 INF INF INF INF"); + command("region top block INF INF 0.0 1.0 INF INF"); + command("region bottom block INF INF 1.0 2.0 INF INF"); + command("region front block INF INF INF INF 0.0 1.0"); + command("region back block INF INF INF 1.0 2.0 INF"); + command("group top region top"); + command("group bottom region bottom"); + END_HIDE_OUTPUT(); + } +}; + +TEST_F(SetTest, NoBoxNoAtoms) +{ + ASSERT_EQ(atom->natoms, 0); + ASSERT_EQ(domain->box_exist, 0); + TEST_FAILURE(".*ERROR: Set command before simulation box is.*", command("set type 1 x 0.0");); + + BEGIN_HIDE_OUTPUT(); + command("region box block 0 2 0 2 0 2"); + command("create_box 1 box"); + END_HIDE_OUTPUT(); + TEST_FAILURE(".*ERROR: Set command on system without atoms.*", command("set type 1 x 0.0");); + + BEGIN_HIDE_OUTPUT(); + command("create_atoms 1 single 0.5 0.5 0.5"); + command("compute 0 all property/atom proc"); + END_HIDE_OUTPUT(); + auto compute = lmp->modify->get_compute_by_id("0"); + compute->compute_peratom(); + ASSERT_EQ(compute->vector_atom[0], 0); + + TEST_FAILURE(".*ERROR: Illegal set command: need at least four.*", command("set type 1 x");); + TEST_FAILURE(".*ERROR: Unknown set command style: xxx.*", command("set xxx 1 x 0.0");); + TEST_FAILURE(".*ERROR: Set keyword or custom property yyy does not exist.*", + command("set type 1 yyy 0.0");); + + TEST_FAILURE(".*ERROR: Cannot set attribute spin/atom for atom style atomic.*", + command("set atom * spin/atom 1.0 1.0 0.0 0.0");); + TEST_FAILURE(".*ERROR: Cannot set attribute spin/atom/random for atom style atomic.*", + command("set atom * spin/atom/random 436273456 1.0");); + + TEST_FAILURE(".*ERROR: Illegal compute property/atom command: missing argument.*", + command("compute 1 all property/atom");); + TEST_FAILURE(".*ERROR: Compute property/atom mol is not available.*", + command("compute 1 all property/atom mol");); +} + +TEST_F(SetTest, StylesTypes) +{ + atomic_system("molecular"); + ASSERT_EQ(atom->natoms, 8); + + BEGIN_HIDE_OUTPUT(); + command("set group all mol 1"); + command("set group top type 2"); + command("set region back type 3"); + command("set region left mol 2"); + command("compute 1 all property/atom id type mol"); + END_HIDE_OUTPUT(); + + auto compute = lmp->modify->get_compute_by_id("1"); + ASSERT_NE(compute, nullptr); + compute->compute_peratom(); + + ASSERT_EQ(atom->type[0], 2); + ASSERT_EQ(atom->type[1], 2); + ASSERT_EQ(atom->type[2], 1); + ASSERT_EQ(atom->type[3], 1); + ASSERT_EQ(atom->type[4], 2); + ASSERT_EQ(atom->type[5], 2); + ASSERT_EQ(atom->type[6], 1); + ASSERT_EQ(atom->type[7], 1); + + ASSERT_EQ(atom->molecule[0], 2); + ASSERT_EQ(atom->molecule[1], 1); + ASSERT_EQ(atom->molecule[2], 2); + ASSERT_EQ(atom->molecule[3], 1); + ASSERT_EQ(atom->molecule[4], 2); + ASSERT_EQ(atom->molecule[5], 1); + ASSERT_EQ(atom->molecule[6], 2); + ASSERT_EQ(atom->molecule[7], 1); + + // atom ID + ASSERT_EQ(compute->array_atom[0][0], 1); + ASSERT_EQ(compute->array_atom[1][0], 2); + ASSERT_EQ(compute->array_atom[2][0], 3); + ASSERT_EQ(compute->array_atom[3][0], 4); + ASSERT_EQ(compute->array_atom[4][0], 5); + ASSERT_EQ(compute->array_atom[5][0], 6); + ASSERT_EQ(compute->array_atom[6][0], 7); + ASSERT_EQ(compute->array_atom[7][0], 8); + + // atom type + ASSERT_EQ(compute->array_atom[0][1], 2); + ASSERT_EQ(compute->array_atom[1][1], 2); + ASSERT_EQ(compute->array_atom[2][1], 1); + ASSERT_EQ(compute->array_atom[3][1], 1); + ASSERT_EQ(compute->array_atom[4][1], 2); + ASSERT_EQ(compute->array_atom[5][1], 2); + ASSERT_EQ(compute->array_atom[6][1], 1); + ASSERT_EQ(compute->array_atom[7][1], 1); + + // mol ID + ASSERT_EQ(compute->array_atom[0][2], 2); + ASSERT_EQ(compute->array_atom[1][2], 1); + ASSERT_EQ(compute->array_atom[2][2], 2); + ASSERT_EQ(compute->array_atom[3][2], 1); + ASSERT_EQ(compute->array_atom[4][2], 2); + ASSERT_EQ(compute->array_atom[5][2], 1); + ASSERT_EQ(compute->array_atom[6][2], 2); + ASSERT_EQ(compute->array_atom[7][2], 1); + + BEGIN_HIDE_OUTPUT(); + command("set mol 1 type 4"); + command("set atom 4*7 type 5"); + END_HIDE_OUTPUT(); + ASSERT_EQ(atom->type[0], 2); + ASSERT_EQ(atom->type[1], 4); + ASSERT_EQ(atom->type[2], 1); + ASSERT_EQ(atom->type[3], 5); + ASSERT_EQ(atom->type[4], 5); + ASSERT_EQ(atom->type[5], 5); + ASSERT_EQ(atom->type[6], 5); + ASSERT_EQ(atom->type[7], 4); + + BEGIN_HIDE_OUTPUT(); + command("variable rev atom 9-id"); + command("set group all type v_rev"); + END_HIDE_OUTPUT(); + ASSERT_EQ(atom->type[0], 8); + ASSERT_EQ(atom->type[1], 7); + ASSERT_EQ(atom->type[2], 6); + ASSERT_EQ(atom->type[3], 5); + ASSERT_EQ(atom->type[4], 4); + ASSERT_EQ(atom->type[5], 3); + ASSERT_EQ(atom->type[6], 2); + ASSERT_EQ(atom->type[7], 1); + + BEGIN_HIDE_OUTPUT(); + command("set group all type 1"); + command("set group all type/fraction 2 0.5 453246"); + END_HIDE_OUTPUT(); + int sum = 0; + for (int i = 0; i < 8; ++i) + sum += (atom->type[i] == 2) ? 1 : 0; + ASSERT_EQ(sum, 4); + + BEGIN_HIDE_OUTPUT(); + command("set group all type 1"); + command("set group all type/ratio 2 0.5 5784536"); + END_HIDE_OUTPUT(); + sum = 0; + for (int i = 0; i < 8; ++i) + sum += (atom->type[i] == 2) ? 1 : 0; + ASSERT_EQ(sum, 4); + + BEGIN_HIDE_OUTPUT(); + command("set group all type 1"); + command("set group all type/subset 2 4 784536"); + END_HIDE_OUTPUT(); + sum = 0; + for (int i = 0; i < 8; ++i) + sum += (atom->type[i] == 2) ? 1 : 0; + ASSERT_EQ(sum, 4); + + TEST_FAILURE(".*ERROR: Numeric index 9 is out of bounds .1-8.*", command("set type 9 x 0.0");); + TEST_FAILURE(".*ERROR: Invalid range string: 3:10.*", command("set type 3:10 x 0.0");); + TEST_FAILURE(".*ERROR: Could not find set group ID nope.*", command("set group nope x 0.0");); +} + +TEST_F(SetTest, PosVelCharge) +{ + atomic_system("charge"); + ASSERT_EQ(atom->natoms, 8); + + BEGIN_HIDE_OUTPUT(); + command("set group top charge 1.0"); + command("set atom 5*8 charge -1.0"); + END_HIDE_OUTPUT(); + ASSERT_EQ(atom->q[0], 1); + ASSERT_EQ(atom->q[1], 1); + ASSERT_EQ(atom->q[2], 0); + ASSERT_EQ(atom->q[3], 0); + ASSERT_EQ(atom->q[4], -1); + ASSERT_EQ(atom->q[5], -1); + ASSERT_EQ(atom->q[6], -1); + ASSERT_EQ(atom->q[7], -1); + + BEGIN_HIDE_OUTPUT(); + command("variable xpos atom 0.5-x"); + command("variable ypos atom y*0.5"); + command("set atom * x v_xpos y v_ypos z 0.5"); + command("set group all vx v_xpos vy v_ypos vz 0.5"); + END_HIDE_OUTPUT(); + ASSERT_EQ(atom->x[0][0], 0.375); + ASSERT_EQ(atom->x[0][1], 0.0625); + ASSERT_EQ(atom->x[0][2], 0.5); + ASSERT_EQ(atom->x[1][0], -0.625); + ASSERT_EQ(atom->x[1][1], 0.0625); + ASSERT_EQ(atom->x[1][2], 0.5); + ASSERT_EQ(atom->x[2][0], 0.375); + ASSERT_EQ(atom->x[2][1], 0.5625); + ASSERT_EQ(atom->x[2][2], 0.5); + ASSERT_EQ(atom->x[3][0], -0.625); + ASSERT_EQ(atom->x[3][1], 0.5625); + ASSERT_EQ(atom->x[3][2], 0.5); + ASSERT_EQ(atom->x[4][0], 0.375); + ASSERT_EQ(atom->x[4][1], 0.0625); + ASSERT_EQ(atom->x[4][2], 0.5); + ASSERT_EQ(atom->x[5][0], -0.625); + ASSERT_EQ(atom->x[5][1], 0.0625); + ASSERT_EQ(atom->x[5][2], 0.5); + ASSERT_EQ(atom->x[6][0], 0.375); + ASSERT_EQ(atom->x[6][1], 0.5625); + ASSERT_EQ(atom->x[6][2], 0.5); + ASSERT_EQ(atom->x[7][0], -0.625); + ASSERT_EQ(atom->x[7][1], 0.5625); + ASSERT_EQ(atom->x[7][2], 0.5); + + ASSERT_EQ(atom->v[0][0], 0.125); + ASSERT_EQ(atom->v[0][1], 0.03125); + ASSERT_EQ(atom->v[0][2], 0.5); + ASSERT_EQ(atom->v[1][0], 1.125); + ASSERT_EQ(atom->v[1][1], 0.03125); + ASSERT_EQ(atom->v[1][2], 0.5); + ASSERT_EQ(atom->v[2][0], 0.125); + ASSERT_EQ(atom->v[2][1], 0.28125); + ASSERT_EQ(atom->v[2][2], 0.5); + ASSERT_EQ(atom->v[3][0], 1.125); + ASSERT_EQ(atom->v[3][1], 0.28125); + ASSERT_EQ(atom->v[3][2], 0.5); + ASSERT_EQ(atom->v[4][0], 0.125); + ASSERT_EQ(atom->v[4][1], 0.03125); + ASSERT_EQ(atom->v[4][2], 0.5); + ASSERT_EQ(atom->v[5][0], 1.125); + ASSERT_EQ(atom->v[5][1], 0.03125); + ASSERT_EQ(atom->v[5][2], 0.5); + ASSERT_EQ(atom->v[6][0], 0.125); + ASSERT_EQ(atom->v[6][1], 0.28125); + ASSERT_EQ(atom->v[6][2], 0.5); + ASSERT_EQ(atom->v[7][0], 1.125); + ASSERT_EQ(atom->v[7][1], 0.28125); + ASSERT_EQ(atom->v[7][2], 0.5); +} + +TEST_F(SetTest, SpinPackage) +{ + if (!Info::has_package("SPIN")) GTEST_SKIP(); + atomic_system("spin"); + ASSERT_EQ(atom->natoms, 8); + + BEGIN_HIDE_OUTPUT(); + command("set atom 1*2 spin/atom 0.5 0.1 0.5 -0.1"); + command("set atom 8 spin/atom/random 23974 0.25"); + END_HIDE_OUTPUT(); + constexpr double vx = 0.1; + constexpr double vy = 0.5; + constexpr double vz = -0.1; + constexpr double norm = 1.0 / sqrt(vx * vx + vy * vy + vz * vz); + ASSERT_EQ(atom->sp[0][0], vx * norm); + ASSERT_EQ(atom->sp[0][1], vy * norm); + ASSERT_EQ(atom->sp[0][2], vz * norm); + ASSERT_EQ(atom->sp[0][3], 0.5); + ASSERT_EQ(atom->sp[1][0], vx * norm); + ASSERT_EQ(atom->sp[1][1], vy * norm); + ASSERT_EQ(atom->sp[1][2], vz * norm); + ASSERT_EQ(atom->sp[1][3], 0.5); + ASSERT_NE(atom->sp[7][0], 0.0); + ASSERT_NE(atom->sp[7][1], 0.0); + ASSERT_NE(atom->sp[7][2], 0.0); + ASSERT_EQ(atom->sp[7][3], 0.25); + + for (int i = 2; i < 7; ++i) + for (int j = 0; j < 4; ++j) + ASSERT_EQ(atom->sp[i][j], 0); + + TEST_FAILURE(".*ERROR: Invalid spin magnitude -0.1 in set spin/atom command.*", + command("set atom * spin/atom -0.1 1.0 0.0 0.0");); + TEST_FAILURE(".*ERROR: At least one spin vector component must be non-zero.*", + command("set atom * spin/atom 1.0 0.0 0.0 0.0");); + TEST_FAILURE(".*ERROR: Invalid spin magnitude -0.2 in set spin/atom/random command.*", + command("set atom * spin/atom/random 436273456 -0.2");); + TEST_FAILURE(".*ERROR: Invalid random number seed 0 in set spin/atom/random command.*", + command("set atom * spin/atom/random 0 1.0");); +} + +TEST_F(SetTest, EffPackage) +{ + if (!Info::has_package("EFF")) GTEST_SKIP(); + atomic_system("electron"); + ASSERT_EQ(atom->natoms, 8); + + BEGIN_HIDE_OUTPUT(); + command("set atom 1*2 spin/electron -1"); + command("set atom 3*4 spin/electron 1"); + command("set atom 5 spin/electron 0"); + command("set atom 6 spin/electron 2"); + command("set atom 7* spin/electron 3"); + command("set region left radius/electron 0.5"); + command("set region right radius/electron 1.0"); + command("compute 2 all property/atom espin eradius"); + END_HIDE_OUTPUT(); + + auto compute = lmp->modify->get_compute_by_id("2"); + ASSERT_NE(compute, nullptr); + compute->compute_peratom(); + + EXPECT_EQ(atom->spin[0],-1); + EXPECT_EQ(atom->spin[1],-1); + EXPECT_EQ(atom->spin[2],1); + EXPECT_EQ(atom->spin[3],1); + EXPECT_EQ(atom->spin[4],0); + EXPECT_EQ(atom->spin[5],2); + EXPECT_EQ(atom->spin[6],3); + EXPECT_EQ(atom->spin[7],3); + EXPECT_EQ(atom->eradius[0],0.5); + EXPECT_EQ(atom->eradius[1],1.0); + EXPECT_EQ(atom->eradius[2],0.5); + EXPECT_EQ(atom->eradius[3],1.0); + EXPECT_EQ(atom->eradius[4],0.5); + EXPECT_EQ(atom->eradius[5],1.0); + EXPECT_EQ(atom->eradius[6],0.5); + EXPECT_EQ(atom->eradius[7],1.0); + + EXPECT_EQ(compute->array_atom[0][0],-1); + EXPECT_EQ(compute->array_atom[1][0],-1); + EXPECT_EQ(compute->array_atom[2][0],1); + EXPECT_EQ(compute->array_atom[3][0],1); + EXPECT_EQ(compute->array_atom[4][0],0); + EXPECT_EQ(compute->array_atom[5][0],2); + EXPECT_EQ(compute->array_atom[6][0],3); + EXPECT_EQ(compute->array_atom[7][0],3); + EXPECT_EQ(compute->array_atom[0][1],0.5); + EXPECT_EQ(compute->array_atom[1][1],1.0); + EXPECT_EQ(compute->array_atom[2][1],0.5); + EXPECT_EQ(compute->array_atom[3][1],1.0); + EXPECT_EQ(compute->array_atom[4][1],0.5); + EXPECT_EQ(compute->array_atom[5][1],1.0); + EXPECT_EQ(compute->array_atom[6][1],0.5); + EXPECT_EQ(compute->array_atom[7][1],1.0); + + TEST_FAILURE(".*ERROR on proc 0: Incorrect value for electron spin: 0.5.*", + command("set atom * spin/electron 0.5");); + TEST_FAILURE(".*ERROR on proc 0: Incorrect value for electron radius: -0.5.*", + command("set atom * radius/electron -0.5");); +} + +} // namespace LAMMPS_NS + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + ::testing::InitGoogleMock(&argc, argv); + + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; + + // handle arguments passed via environment variable + if (const char *var = getenv("TEST_ARGS")) { + std::vector env = LAMMPS_NS::utils::split_words(var); + for (auto arg : env) { + if (arg == "-v") { + verbose = true; + } + } + } + + if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; + + int rv = RUN_ALL_TESTS(); + MPI_Finalize(); + return rv; +} diff --git a/unittest/commands/test_simple_commands.cpp b/unittest/commands/test_simple_commands.cpp index ccec6321b3..5889f09eb0 100644 --- a/unittest/commands/test_simple_commands.cpp +++ b/unittest/commands/test_simple_commands.cpp @@ -36,8 +36,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { using ::testing::ContainsRegex; using ::testing::ExitedWithCode; @@ -552,12 +550,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index bf3f0cc5e9..848331abe2 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -32,13 +32,11 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::MathConst::MY_PI; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { using ::testing::ContainsRegex; using ::testing::ExitedWithCode; using ::testing::StrEq; +using MathConst::MY_PI; class VariableTest : public LAMMPSTest { protected: @@ -585,12 +583,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/cplusplus/test_advanced_utils.cpp b/unittest/cplusplus/test_advanced_utils.cpp index 63c029c068..6b71c9ea34 100644 --- a/unittest/cplusplus/test_advanced_utils.cpp +++ b/unittest/cplusplus/test_advanced_utils.cpp @@ -16,7 +16,6 @@ bool verbose = false; namespace LAMMPS_NS { - class Advanced_utils : public LAMMPSTest { protected: Error *error; @@ -218,7 +217,6 @@ TEST_F(Advanced_utils, expand_args) delete[] args[i]; delete[] args; } - } // namespace LAMMPS_NS int main(int argc, char **argv) @@ -226,12 +224,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/cplusplus/test_error_class.cpp b/unittest/cplusplus/test_error_class.cpp index ba3187cd61..779cbfbba6 100644 --- a/unittest/cplusplus/test_error_class.cpp +++ b/unittest/cplusplus/test_error_class.cpp @@ -16,9 +16,7 @@ bool verbose = false; namespace LAMMPS_NS { - using ::testing::ContainsRegex; -using utils::split_words; class Error_class : public LAMMPSTest { protected: @@ -120,7 +118,6 @@ TEST_F(Error_class, all) { TEST_FAILURE("ERROR: one error.*test_error_class.cpp:.*", error->all(FLERR, "one error");); }; - } // namespace LAMMPS_NS int main(int argc, char **argv) @@ -128,12 +125,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/compressed_dump_test_main.cpp b/unittest/formats/compressed_dump_test_main.cpp index c96682d8b7..5f775a8843 100644 --- a/unittest/formats/compressed_dump_test_main.cpp +++ b/unittest/formats/compressed_dump_test_main.cpp @@ -50,7 +50,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/test_dump_atom.cpp b/unittest/formats/test_dump_atom.cpp index 762a01e648..12dd8bee8a 100644 --- a/unittest/formats/test_dump_atom.cpp +++ b/unittest/formats/test_dump_atom.cpp @@ -28,6 +28,8 @@ using ::testing::Eq; char *BINARY2TXT_EXECUTABLE = nullptr; bool verbose = false; +namespace LAMMPS_NS { + class DumpAtomTest : public MeltTest { std::string dump_style = "atom"; @@ -678,6 +680,7 @@ TEST_F(DumpAtomTest, binary_write_dump) delete_file(reference); delete_file(dump_file); } +} int main(int argc, char **argv) { @@ -686,7 +689,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/test_dump_cfg.cpp b/unittest/formats/test_dump_cfg.cpp index e51da8331a..acd839282d 100644 --- a/unittest/formats/test_dump_cfg.cpp +++ b/unittest/formats/test_dump_cfg.cpp @@ -23,6 +23,7 @@ using ::testing::Eq; bool verbose = false; +namespace LAMMPS_NS { class DumpCfgTest : public MeltTest { std::string dump_style = "cfg"; @@ -143,6 +144,7 @@ TEST_F(DumpCfgTest, no_unwrap_no_buffer_run0) ASSERT_THAT(lines[0], Eq("Number of particles = 32")); delete_file("dump_cfg_no_unwrap_no_buffer_run0.melt.cfg"); } +} int main(int argc, char **argv) { @@ -151,7 +153,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/test_dump_custom.cpp b/unittest/formats/test_dump_custom.cpp index 72b4adcc87..d1bae9d28f 100644 --- a/unittest/formats/test_dump_custom.cpp +++ b/unittest/formats/test_dump_custom.cpp @@ -26,6 +26,7 @@ using ::testing::Eq; char *BINARY2TXT_EXECUTABLE = nullptr; bool verbose = false; +namespace LAMMPS_NS { class DumpCustomTest : public MeltTest { std::string dump_style = "custom"; @@ -383,7 +384,7 @@ TEST_F(DumpCustomTest, rerun_bin) ASSERT_NEAR(pe_2, pe_rerun, 1.0e-14); delete_file(dump_file); } - +} int main(int argc, char **argv) { MPI_Init(&argc, &argv); @@ -391,7 +392,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/test_dump_local.cpp b/unittest/formats/test_dump_local.cpp index ead071743c..5735f4dc7c 100644 --- a/unittest/formats/test_dump_local.cpp +++ b/unittest/formats/test_dump_local.cpp @@ -28,6 +28,7 @@ using ::testing::Eq; char *BINARY2TXT_EXECUTABLE = nullptr; bool verbose = false; +namespace LAMMPS_NS { class DumpLocalTest : public MeltTest { std::string dump_style = "local"; @@ -237,6 +238,7 @@ TEST_F(DumpLocalTest, triclinic_run0) ASSERT_EQ(utils::split_words(lines[7]).size(), 3); delete_file(dump_file); } +} int main(int argc, char **argv) { @@ -245,7 +247,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/test_dump_netcdf.cpp b/unittest/formats/test_dump_netcdf.cpp index 6d377369ee..0b016d0efb 100644 --- a/unittest/formats/test_dump_netcdf.cpp +++ b/unittest/formats/test_dump_netcdf.cpp @@ -31,6 +31,7 @@ using ::testing::Eq; char *NCDUMP_EXECUTABLE = nullptr; bool verbose = false; +namespace LAMMPS_NS { class DumpNetCDFTest : public MeltTest { std::string dump_style = "netcdf"; @@ -386,6 +387,7 @@ TEST_F(DumpNetCDFTest, run0_mpi) } delete_file(dump_file); } +} int main(int argc, char **argv) { @@ -394,7 +396,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/testing/core.h b/unittest/testing/core.h index 81a7112934..5b2aba6fd3 100644 --- a/unittest/testing/core.h +++ b/unittest/testing/core.h @@ -26,7 +26,9 @@ #include #include -using namespace LAMMPS_NS; +using LAMMPS_NS::Info; +using LAMMPS_NS::LAMMPS; +using LAMMPS_NS::LAMMPSException; using ::testing::ContainsRegex; @@ -37,7 +39,7 @@ using ::testing::ContainsRegex; auto mesg = ::testing::internal::GetCapturedStdout(); \ ASSERT_THAT(mesg, ContainsRegex(errmsg)); \ } else { \ - if (platform::mpi_vendor() != "Open MPI") { \ + if (LAMMPS_NS::platform::mpi_vendor() != "Open MPI") { \ ::testing::internal::CaptureStdout(); \ ASSERT_DEATH({__VA_ARGS__}, ""); \ auto mesg = ::testing::internal::GetCapturedStdout(); \ @@ -101,7 +103,7 @@ public: double get_variable_value(const std::string &name) { - char *str = utils::strdup(fmt::format("v_{}", name)); + char *str = LAMMPS_NS::utils::strdup(fmt::format("v_{}", name)); double value = lmp->input->variable->compute_equal(str); delete[] str; return value; @@ -122,9 +124,9 @@ protected: { int argc = args.size() + 1; char **argv = new char *[argc]; - argv[0] = utils::strdup(testbinary); + argv[0] = LAMMPS_NS::utils::strdup(testbinary); for (int i = 1; i < argc; i++) { - argv[i] = utils::strdup(args[i - 1]); + argv[i] = LAMMPS_NS::utils::strdup(args[i - 1]); } HIDE_OUTPUT([&] {