From 8934d034756bddf474928c8857a280439c4165b1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 26 Feb 2026 10:55:17 -0500 Subject: [PATCH 01/23] warnings should only be printed on MPI rank 0 --- src/MC/fix_gcmc.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp index e697663a7a3..dc59e9d1e9c 100644 --- a/src/MC/fix_gcmc.cpp +++ b/src/MC/fix_gcmc.cpp @@ -280,7 +280,7 @@ void FixGCMC::options(int narg, char **arg) if (imol == -1) error->all(FLERR, iarg + 1, "Molecule template ID {} for fix gcmc does not exist", arg[iarg + 1]); - if (atom->molecules[imol]->nset > 1 && comm->me == 0) + if ((atom->molecules[imol]->nset > 1) && (comm->me == 0)) error->warning(FLERR, "Molecule template for fix gcmc has multiple molecules"); exchmode = EXCHMOL; onemols = atom->molecules; @@ -712,8 +712,7 @@ void FixGCMC::init() // warning if group id is "all" if ((comm->me == 0) && (groupbit & 1)) - error->warning(FLERR, "Fix gcmc is being applied " - "to the default group all"); + error->warning(FLERR, "Fix gcmc is being applied ""to the default group all"); // construct group bitmask for all new atoms // aggregated over all group keywords @@ -790,9 +789,8 @@ void FixGCMC::pre_exchange() if (full_flag) { energy_stored = energy_full(); - if (overlap_flag && energy_stored > MAXENERGYTEST) - error->warning(FLERR,"Energy of old configuration in " - "fix gcmc is > MAXENERGYTEST."); + if (overlap_flag && (energy_stored > MAXENERGYTEST) && (comm->me == 0)) + error->warning(FLERR,"Energy of old configuration in fix gcmc is > MAXENERGYTEST."); for (int i = 0; i < ncycles; i++) { int ixm = static_cast(random_equal->uniform()*ncycles) + 1; @@ -861,8 +859,8 @@ void FixGCMC::attempt_atomic_translation() if (i >= 0) { double **x = atom->x; double energy_before = energy(i,ngcmc_type,-1,x[i]); - if (overlap_flag && energy_before > MAXENERGYTEST) - error->warning(FLERR,"Energy of old configuration in fix gcmc is > MAXENERGYTEST."); + if (overlap_flag && (energy_before > MAXENERGYTEST) && (comm->me == 0)) + error->warning(FLERR,"Energy of old configuration in fix gcmc is > MAXENERGYTEST."); double rsq = 1.1; double rx,ry,rz; rx = ry = rz = 0.0; @@ -1085,9 +1083,8 @@ void FixGCMC::attempt_molecule_translation() if (translation_molecule == -1) return; double energy_before_sum = molecule_energy(translation_molecule); - if (overlap_flag && energy_before_sum > MAXENERGYTEST) - error->warning(FLERR,"Energy of old configuration in " - "fix gcmc is > MAXENERGYTEST."); + if (overlap_flag && (energy_before_sum > MAXENERGYTEST) && (comm->me == 0)) + error->warning(FLERR,"Energy of old configuration in fix gcmc is > MAXENERGYTEST."); double **x = atom->x; double rx,ry,rz; @@ -1184,9 +1181,8 @@ void FixGCMC::attempt_molecule_rotation() if (rotation_molecule == -1) return; double energy_before_sum = molecule_energy(rotation_molecule); - if (overlap_flag && energy_before_sum > MAXENERGYTEST) - error->warning(FLERR,"Energy of old configuration in " - "fix gcmc is > MAXENERGYTEST."); + if (overlap_flag && (energy_before_sum > MAXENERGYTEST) && (comm->me == 0)) + error->warning(FLERR,"Energy of old configuration in fix gcmc is > MAXENERGYTEST."); int *mask = atom->mask; int nmolcoords = 0; From 3911b91b5511b8270437b6c5c3a1223837439233 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 26 Feb 2026 11:27:26 -0500 Subject: [PATCH 02/23] avoid getting stuck in region restricted MC moves and improve errors --- src/MC/fix_gcmc.cpp | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp index dc59e9d1e9c..a66a461ca1b 100644 --- a/src/MC/fix_gcmc.cpp +++ b/src/MC/fix_gcmc.cpp @@ -875,6 +875,7 @@ void FixGCMC::attempt_atomic_translation() coord[1] = x[i][1] + displace*ry; coord[2] = x[i][2] + displace*rz; if (region) { + int region_attempt = 0; while (region->match(coord[0],coord[1],coord[2]) == 0) { rsq = 1.1; while (rsq > 1.0) { @@ -886,10 +887,14 @@ void FixGCMC::attempt_atomic_translation() coord[0] = x[i][0] + displace*rx; coord[1] = x[i][1] + displace*ry; coord[2] = x[i][2] + displace*rz; + ++region_attempt; + if (region_attempt >= max_region_attempts) break; } + if (!region->match(coord[0],coord[1],coord[2])) + error->one(FLERR,"Fix gcmc translation put atom outside region"); } if (!domain->inside_nonperiodic(coord)) - error->one(FLERR,"Fix gcmc put atom outside box"); + error->one(FLERR,"Fix gcmc translation put atom outside box"); double energy_after = energy(i,ngcmc_type,-1,coord); @@ -1115,6 +1120,7 @@ void FixGCMC::attempt_molecule_translation() coord[0] = com[0] + displace*rx; coord[1] = com[1] + displace*ry; coord[2] = com[2] + displace*rz; + int region_attempt = 0; while (region->match(coord[0],coord[1],coord[2]) == 0) { rsq = 1.1; while (rsq > 1.0) { @@ -1126,10 +1132,14 @@ void FixGCMC::attempt_molecule_translation() coord[0] = com[0] + displace*rx; coord[1] = com[1] + displace*ry; coord[2] = com[2] + displace*rz; + ++region_attempt; + if (region_attempt >= max_region_attempts) break; } com_displace[0] = displace*rx; com_displace[1] = displace*ry; com_displace[2] = displace*rz; + if (!region->match(coord[0],coord[1],coord[2])) + error->one(FLERR,"Fix gcmc translation put molecule COM outside region"); } double energy_after = 0.0; @@ -1139,7 +1149,7 @@ void FixGCMC::attempt_molecule_translation() coord[1] = x[i][1] + com_displace[1]; coord[2] = x[i][2] + com_displace[2]; if (!domain->inside_nonperiodic(coord)) - error->one(FLERR,"Fix gcmc put atom outside box"); + error->one(FLERR,"Fix gcmc translation put molecule atom outside box"); energy_after += energy(i,atom->type[i],translation_molecule,coord); } } @@ -1330,8 +1340,7 @@ void FixGCMC::attempt_molecule_insertion() (region_yhi-region_ylo); com_coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo); - while (region->match(com_coord[0],com_coord[1], - com_coord[2]) == 0) { + while (region->match(com_coord[0],com_coord[1],com_coord[2]) == 0) { com_coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo); com_coord[1] = region_ylo + random_equal->uniform() * @@ -1542,6 +1551,7 @@ void FixGCMC::attempt_atomic_translation_full() coord[1] = x[i][1] + displace*ry; coord[2] = x[i][2] + displace*rz; if (region) { + int region_attempt = 0; while (region->match(coord[0],coord[1],coord[2]) == 0) { rsq = 1.1; while (rsq > 1.0) { @@ -1553,10 +1563,14 @@ void FixGCMC::attempt_atomic_translation_full() coord[0] = x[i][0] + displace*rx; coord[1] = x[i][1] + displace*ry; coord[2] = x[i][2] + displace*rz; + ++region_attempt; + if (region_attempt >= max_region_attempts) break; } + if (!region->match(coord[0],coord[1],coord[2])) + error->one(FLERR,"Fix gcmc translation put atom outside region"); } if (!domain->inside_nonperiodic(coord)) - error->one(FLERR,"Fix gcmc put atom outside box"); + error->one(FLERR,"Fix gcmc translation put atom outside box"); xtmp[0] = x[i][0]; xtmp[1] = x[i][1]; xtmp[2] = x[i][2]; @@ -1791,6 +1805,7 @@ void FixGCMC::attempt_molecule_translation_full() mask[i] &= molecule_group_inversebit; } } + int region_attempt = 0; double com[3]; com[0] = com[1] = com[2] = 0.0; group->xcm(molecule_group,gas_mass,com); @@ -1808,7 +1823,11 @@ void FixGCMC::attempt_molecule_translation_full() coord[0] = com[0] + displace*rx; coord[1] = com[1] + displace*ry; coord[2] = com[2] + displace*rz; + ++region_attempt; + if (region_attempt >= max_region_attempts) break; } + if (!region->match(coord[0],coord[1],coord[2])) + error->one(FLERR,"Fix gcmc translation put molecule COM outside region"); com_displace[0] = displace*rx; com_displace[1] = displace*ry; com_displace[2] = displace*rz; @@ -1820,7 +1839,7 @@ void FixGCMC::attempt_molecule_translation_full() x[i][1] += com_displace[1]; x[i][2] += com_displace[2]; if (!domain->inside_nonperiodic(x[i])) - error->one(FLERR,"Fix gcmc put atom outside box"); + error->one(FLERR,"Fix gcmc put molecule atom outside box"); } } @@ -2062,8 +2081,7 @@ void FixGCMC::attempt_molecule_insertion_full() (region_yhi-region_ylo); com_coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo); - while (region->match(com_coord[0],com_coord[1], - com_coord[2]) == 0) { + while (region->match(com_coord[0],com_coord[1],com_coord[2]) == 0) { com_coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo); com_coord[1] = region_ylo + random_equal->uniform() * @@ -2491,8 +2509,7 @@ void FixGCMC::update_gas_atoms_list() for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { - if (region->match(comx[molecule[i]], - comy[molecule[i]],comz[molecule[i]]) == 1) { + if (region->match(comx[molecule[i]],comy[molecule[i]],comz[molecule[i]]) == 1) { local_gas_list[ngas_local] = i; ngas_local++; } From fe09513dd8d0ee6b3472b3f859fb957e709fdf5f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 26 Feb 2026 12:05:59 -0500 Subject: [PATCH 03/23] use PPM format images instead of PNG for better compatibility --- examples/GRAPHICS/in.breakable | 2 +- examples/GRAPHICS/in.cubes-and-pyramids | 2 +- examples/GRAPHICS/in.obstacle-lines | 84 ++++++++++++------------- examples/GRAPHICS/in.peptide-hbonds | 2 +- examples/GRAPHICS/in.water-arrows | 2 +- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/examples/GRAPHICS/in.breakable b/examples/GRAPHICS/in.breakable index d483a000313..f92eadee201 100644 --- a/examples/GRAPHICS/in.breakable +++ b/examples/GRAPHICS/in.breakable @@ -86,7 +86,7 @@ fix labels all graphics/labels 500 text "LAMMPS Tutorial 2 - Stretching CNT usi text "Atoms with bonds 1: $(c_count[1]) 2: $(c_count[2]) 3: $(c_count[3]) 4: $(c_count[4])" & 32.5 7.5 5.0 size 24 fontcolor white backcolor silver -dump viz all image 500 breakable.*.png c_nbond type size 1600 300 zoom 12.5 shiny 0.2 autobond 1.8 0.4 & +dump viz all image 500 breakable.*.ppm c_nbond type size 1600 300 zoom 12.5 shiny 0.2 autobond 1.8 0.4 & adiam 0.8 box no 0.01 view 0 90 fsaa yes ssao yes 1325123 0.6 axes yes 0.5 0.1 & fix arrows const 0 0 fix labels const 0 0 fix vel const 0 0 diff --git a/examples/GRAPHICS/in.cubes-and-pyramids b/examples/GRAPHICS/in.cubes-and-pyramids index bd924e73954..bed142c5151 100644 --- a/examples/GRAPHICS/in.cubes-and-pyramids +++ b/examples/GRAPHICS/in.cubes-and-pyramids @@ -45,7 +45,7 @@ thermo 1000 variable progress equal step/v_steps fix pbar all graphics/objects ${out} progbar 3 4 y 24.0 12.0 -1.4 30.0 0.5 v_progress 10 -dump 2 all image ${out} cubes-and-pyramids.*.png type type size 600 600 shiny 0.4 & +dump 2 all image ${out} cubes-and-pyramids.*.ppm type type size 600 600 shiny 0.4 & box yes 0.025 axes no 0.5 0.1 zoom 1.5 view 80 0 fsaa yes ssao yes 315123 0.4 & body type 0.2 3 fix pbar type 0 0 # set cylinder diameter--^ ^-- set viz style (1 only faces, 2 cylinders, 3 both) diff --git a/examples/GRAPHICS/in.obstacle-lines b/examples/GRAPHICS/in.obstacle-lines index c9d06bfa788..6c9bd5b54cc 100644 --- a/examples/GRAPHICS/in.obstacle-lines +++ b/examples/GRAPHICS/in.obstacle-lines @@ -1,70 +1,70 @@ # 2d LJ obstacle flow -dimension 2 -boundary p s p +dimension 2 +boundary p s p -atom_style atomic -neighbor 0.3 bin -neigh_modify delay 5 +atom_style atomic +neighbor 0.3 bin +neigh_modify delay 5 # create geometry -lattice hex 0.7 -region box block 0 40 0 10 -0.25 0.25 -create_box 4 box -create_atoms 1 box +lattice hex 0.7 +region box block 0 40 0 10 -0.25 0.25 +create_box 4 box +create_atoms 1 box -mass * 1.0 +mass * 1.0 # LJ potentials -pair_style lj/cut 1.12246 -pair_coeff * * 1.0 1.0 1.12246 +pair_style lj/cut 1.12246 +pair_coeff * * 1.0 1.0 1.12246 # define groups -region 1 block INF INF INF 1.25 INF INF -group lower region 1 -region 2 block INF INF 8.75 INF INF INF -group upper region 2 -group boundary union lower upper -group flow subtract all boundary +region 1 block INF INF INF 1.25 INF INF +group lower region 1 +region 2 block INF INF 8.75 INF INF INF +group upper region 2 +group boundary union lower upper +group flow subtract all boundary -set group lower type 2 -set group upper type 3 +set group lower type 2 +set group upper type 3 # initial velocities -compute mobile flow temp -velocity flow create 1.0 482748 temp mobile -fix 1 all nve -fix 2 flow temp/rescale 200 1.0 1.0 0.02 1.0 -fix_modify 2 temp mobile +compute mobile flow temp +velocity flow create 1.0 482748 temp mobile +fix 1 all nve +fix 2 flow temp/rescale 200 1.0 1.0 0.02 1.0 +fix_modify 2 temp mobile # Poiselle flow -velocity boundary set 0.0 0.0 0.0 -fix 3 lower setforce 0.0 0.0 0.0 -fix 4 upper setforce 0.0 NULL 0.0 -fix 5 upper aveforce 0.0 -0.5 0.0 -fix 6 flow addforce 1.0 0.0 0.0 +velocity boundary set 0.0 0.0 0.0 +fix 3 lower setforce 0.0 0.0 0.0 +fix 4 upper setforce 0.0 NULL 0.0 +fix 5 upper aveforce 0.0 -0.5 0.0 +fix 6 flow addforce 1.0 0.0 0.0 # 2 obstacles -region void1 sphere 10 4 0 3 -delete_atoms region void1 -region void2 sphere 20 7 0 3 -delete_atoms region void2 +region void1 sphere 10 4 0 3 +delete_atoms region void1 +region void2 sphere 20 7 0 3 +delete_atoms region void2 -fix 7 flow indent 100 sphere 10 4 0 4 -fix 8 flow indent 100 sphere 20 7 0 4 -fix 9 all enforce2d +fix 7 flow indent 100 sphere 10 4 0 4 +fix 8 flow indent 100 sphere 20 7 0 4 +fix 9 all enforce2d # Run -timestep 0.003 -thermo 1000 -thermo_modify temp mobile +timestep 0.003 +thermo 1000 +thermo_modify temp mobile # select atoms to trace and assign atom type 4 so they have a different color (yellow) region trace block 2 3 1.25 8.75 INF INF @@ -74,8 +74,8 @@ set group trace type 4 # create trajectory lines by averaging positions over 10 MD steps each 10 steps apart fix lines trace graphics/lines 10 10 100 25 # visualize the trace in silver with a diameter of 0.6 which is half of that of the atoms -dump viz all image 100 obstacle-*.png type type size 800 600 zoom 2.5 center s 0.50 0.7 0 & +dump viz all image 100 obstacle-*.ppm type type size 800 600 zoom 2.5 center s 0.50 0.7 0 & shiny 0.5 fsaa yes box no 0.025 fix lines const 1 0.6 dump_modify viz pad 6 backcolor darkgray adiam * 1.2 fcolor lines silver -run 30000 +run 30000 diff --git a/examples/GRAPHICS/in.peptide-hbonds b/examples/GRAPHICS/in.peptide-hbonds index 228f54e671c..df1341fb0bc 100644 --- a/examples/GRAPHICS/in.peptide-hbonds +++ b/examples/GRAPHICS/in.peptide-hbonds @@ -53,7 +53,7 @@ fix obj all graphics/objects 100 arrow 5 80.0 61.0 39 80.0 67.0 39 0.3 0.2 & arrow 6 80.0 61.0 37.2 80.0 67.0 37.2 0.3 0.2 # combine the graphics into visualization -dump viz viz image 100 hbonds-*.png element element size 600 600 zoom 2.1 view 80 0 bond atom 0.3 & +dump viz viz image 100 hbonds-*.ppm element element size 600 600 zoom 2.1 view 80 0 bond atom 0.3 & fsaa yes ssao yes 12384 0.6 shiny 0.1 box no 0.1 center s 0.5 0.52 0.52 & compute hb1 const -0.4 0.3 compute hb2 const -0.4 0.3 fix label const 1 0 fix obj type 0.0 0.0 dump_modify viz pad 5 boxcolor white backcolor darkgray backcolor2 silver & diff --git a/examples/GRAPHICS/in.water-arrows b/examples/GRAPHICS/in.water-arrows index 8b9acfb99b4..370419004bf 100644 --- a/examples/GRAPHICS/in.water-arrows +++ b/examples/GRAPHICS/in.water-arrows @@ -58,7 +58,7 @@ variable dip2y equal v_scale*c_dip[2] variable dip2z equal v_scale*c_dip[3] fix dipole all graphics/objects 1 arrow 1 v_dip1x v_dip1y v_dip1z v_dip2x v_dip2y v_dip2z 0.3 0.2 -dump viz all image 10 water-arrows-*.png element type size 600 600 zoom 1.3 shiny 0.2 bond atom 0.2 & +dump viz all image 10 water-arrows-*.ppm element type size 600 600 zoom 1.3 shiny 0.2 bond atom 0.2 & view 70 20 box yes 0.025 fsaa yes ssao yes 315465 0.8 & fix dipole const 0 0 fix vec const 0 0 fix vel const 0 0 fix bin const 0 0 # all arrows from fixes use the "const" style so we set the color with dump_modify below From f647ba8c280307877e82a876b6806fa3cc7f66c9 Mon Sep 17 00:00:00 2001 From: jtclemm Date: Thu, 26 Feb 2026 14:28:23 -0700 Subject: [PATCH 04/23] Fix set structure mismatch for box --- src/EXTRA-FIX/fix_deform_pressure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-FIX/fix_deform_pressure.cpp b/src/EXTRA-FIX/fix_deform_pressure.cpp index 69fa1760d6d..f9169833fac 100644 --- a/src/EXTRA-FIX/fix_deform_pressure.cpp +++ b/src/EXTRA-FIX/fix_deform_pressure.cpp @@ -406,7 +406,7 @@ void FixDeformPressure::init() // reset cumulative counters to match resetting "start" variables in parent - set[6].cumulative_shift = 0.0; + set_box.cumulative_shift = 0.0; for (int i = 0; i < 7; i++) { set_extra[i].cumulative_vshift[0] = 0.0; set_extra[i].cumulative_vshift[1] = 0.0; From 2ea33836d13138f41ca3417cea36877140263fe2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 26 Feb 2026 17:52:15 -0500 Subject: [PATCH 05/23] suggest to check for overlapping atoms also for NaN and Inf values --- doc/src/Errors_details.rst | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/doc/src/Errors_details.rst b/doc/src/Errors_details.rst index 1ab91838b07..2191b857ea8 100644 --- a/doc/src/Errors_details.rst +++ b/doc/src/Errors_details.rst @@ -142,11 +142,24 @@ contacts or bad geometries (for the given force styles in use) leading to forces that can no longer be represented as numbers. Those will show as "NaN" or "Inf". On most machines, the program will continue, but there is no way to recover from it and those NaN or Inf values will -propagate. So-called :doc:`"soft-core" potentials ` or -the :doc:`"soft" repulsive-only pair style ` are less prone -for this behavior (depending on the settings in use) and can be used at -the beginning of a simulation. Also, single precision numbers can -overflow much faster, so for the GPU, KOKKOS, or INTEL package it may be +propagate. + +If the "NaN" or "Inf" appears in the first simulation step, the most +common cause is overlapping atoms. Note that when atoms are *very* +close, this cannot be seen when visualizing the geometry, since the +atoms are effectively sitting on top of each other. A good test is to +insert a command like :doc:`delete_atoms 0.1 all all ` and +then monitor the output to see how many atoms are deleted, if any. A +non-zero number would be an indication of overlapping atoms. Note that +atoms can also overlap through periodic boundaries when the box +dimensions are too small (e.g. determined by min/max position of atoms +without padding). + +So-called :doc:`"soft-core" potentials ` or the +:doc:`"soft" repulsive-only pair style ` are less prone for +this behavior (depending on the settings in use) and can be used at the +beginning of a simulation. Also, single precision numbers can overflow +much faster, so for the GPU, KOKKOS, or INTEL package it may be beneficial to run with double precision initially before switching to mixed or single precision for faster execution when the system has relaxed. From fa415a3ef6bfb83f8a5ec3e9049cefd3dca5eef5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 27 Feb 2026 00:08:19 -0500 Subject: [PATCH 06/23] don't print last line for group bitmask lookup errors --- src/group.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/group.cpp b/src/group.cpp index 5eb9bf9de95..ff515878cd2 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -658,7 +658,8 @@ int Group::get_bitmask_by_id(const std::string &file, int line, const std::strin { int igroup = find(name); if (igroup < 0) - error->all(file, line, "Group ID {} requested by {} does not exist", name, caller); + error->all(file, line, Error::NOLASTLINE, "Group ID {} requested by {} does not exist", name, + caller); return bitmask[igroup]; } From 79f401e49285fc8ac1972458d5df0d7292d78685 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 27 Feb 2026 00:08:30 -0500 Subject: [PATCH 07/23] re-apply clang-format --- src/group.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/group.cpp b/src/group.cpp index ff515878cd2..4ee2dd79c3d 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -668,7 +668,7 @@ int Group::get_bitmask_by_id(const std::string &file, int line, const std::strin ------------------------------------------------------------------------- */ int Group::get_inversemask_by_id(const std::string &file, int line, const std::string &name, - const std::string &caller) + const std::string &caller) { int igroup = find(name); if (igroup < 0) @@ -704,7 +704,7 @@ void Group::add_molecules(int /*igroup*/, int bit) memory->create(list, n, "group:list"); n = 0; - for(const auto pos : hash) list[n++] = pos; + for (const auto pos : hash) list[n++] = pos; molbit = bit; comm->ring(n, sizeof(tagint), list, 1, molring, nullptr, (void *) this); From d3c25783be34e8573801c29f5aed5bae21b0b584 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 27 Feb 2026 01:21:37 -0500 Subject: [PATCH 08/23] improve error message --- src/neighbor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 6496a8c39af..a532f09b1ab 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -856,7 +856,8 @@ int Neighbor::init_pair() if (requests[i]->cut) { if (comm_cutoff < (requests[i]->cutoff + (requests[i]->occasional ? 0.0 : skin))) error->all(FLERR, Error::NOLASTLINE, - "Custom neighbor list cutoff too large for communication cutoff"); + "Custom neighbor list cutoff {} is too large for communication cutoff {}", + (requests[i]->cutoff + (requests[i]->occasional ? 0.0 : skin)), comm_cutoff); } } From 06fc47e2d6f46b31c8270c13bb9cbc3da9cfab4b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 27 Feb 2026 10:03:31 -0500 Subject: [PATCH 09/23] must clamp hi/lo values of regions to box boundaries in case they were set to INF --- src/GRAPHICS/dump_image.cpp | 93 ++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/src/GRAPHICS/dump_image.cpp b/src/GRAPHICS/dump_image.cpp index e943e11b478..f631ffa2028 100644 --- a/src/GRAPHICS/dump_image.cpp +++ b/src/GRAPHICS/dump_image.cpp @@ -1689,7 +1689,7 @@ void DumpImage::create_image() vec3{objarray[i][4], objarray[i][5], objarray[i][6]}, color, opacity); } else if (objvec[i] == Graphics::PIXMAP) { // get pointer to pixmap buffer and get background transparency color - const auto *pixmap = (const unsigned char *) ubuf(objarray[i][6]).i; // NOLINT + const auto *pixmap = (const unsigned char *) ubuf(objarray[i][6]).i; // NOLINT double transcolor[3] = {objarray[i][7], objarray[i][8], objarray[i][9]}; if (iobj.flag1 == 0.0) // coordinates are in box coordinates image->draw_pixmap(&objarray[i][1], (int) objarray[i][4], (int) objarray[i][5], pixmap, @@ -1820,11 +1820,17 @@ void DumpImage::create_image() // inconsistent style. should not happen. if (!myreg) continue; - corners = cornerdata{ - vec3{myreg->xlo, myreg->ylo, myreg->zlo}, vec3{myreg->xlo, myreg->ylo, myreg->zhi}, - vec3{myreg->xlo, myreg->yhi, myreg->zhi}, vec3{myreg->xlo, myreg->yhi, myreg->zlo}, - vec3{myreg->xhi, myreg->ylo, myreg->zlo}, vec3{myreg->xhi, myreg->ylo, myreg->zhi}, - vec3{myreg->xhi, myreg->yhi, myreg->zhi}, vec3{myreg->xhi, myreg->yhi, myreg->zlo}}; + // clamp region boundaries to box boundaries + double xlo = MAX(myreg->xlo, domain->boxlo[0]); + double ylo = MAX(myreg->ylo, domain->boxlo[1]); + double zlo = MAX(myreg->zlo, domain->boxlo[2]); + double xhi = MIN(myreg->xhi, domain->boxhi[0]); + double yhi = MIN(myreg->yhi, domain->boxhi[1]); + double zhi = MIN(myreg->zhi, domain->boxhi[2]); + + corners = cornerdata{vec3{xlo, ylo, zlo}, vec3{xlo, ylo, zhi}, vec3{xlo, yhi, zhi}, + vec3{xlo, yhi, zlo}, vec3{xhi, ylo, zlo}, vec3{xhi, ylo, zhi}, + vec3{xhi, yhi, zhi}, vec3{xhi, yhi, zlo}}; } if (regstyle == "prism") { @@ -1832,24 +1838,32 @@ void DumpImage::create_image() // inconsistent style. should not happen. if (!myreg) continue; + // clamp region boundaries to box boundaries + double xlo = MAX(myreg->xlo, domain->boxlo[0]); + double ylo = MAX(myreg->ylo, domain->boxlo[1]); + double zlo = MAX(myreg->zlo, domain->boxlo[2]); + double xhi = MIN(myreg->xhi, domain->boxhi[0]); + double yhi = MIN(myreg->yhi, domain->boxhi[1]); + double zhi = MIN(myreg->zhi, domain->boxhi[2]); + corners = cornerdata{ - vec3{myreg->xlo, myreg->ylo, myreg->zlo}, - vec3{myreg->xlo + myreg->xz, myreg->ylo + myreg->yz, myreg->zhi}, - vec3{myreg->xlo + myreg->xy + myreg->xz, myreg->yhi + myreg->yz, myreg->zhi}, - vec3{myreg->xlo + myreg->xy, myreg->yhi, myreg->zlo}, - vec3{myreg->xhi, myreg->ylo, myreg->zlo}, - vec3{myreg->xhi + myreg->xz, myreg->ylo + myreg->yz, myreg->zhi}, - vec3{myreg->xhi + myreg->xy + myreg->xz, myreg->yhi + myreg->yz, myreg->zhi}, - vec3{myreg->xhi + myreg->xy, myreg->yhi, myreg->zlo}}; + vec3{xlo, ylo, zlo}, + vec3{xlo + myreg->xz, ylo + myreg->yz, zhi}, + vec3{xlo + myreg->xy + myreg->xz, yhi + myreg->yz, zhi}, + vec3{xlo + myreg->xy, yhi, zlo}, + vec3{xhi, ylo, zlo}, + vec3{xhi + myreg->xz, ylo + myreg->yz, zhi}, + vec3{xhi + myreg->xy + myreg->xz, yhi + myreg->yz, zhi}, + vec3{xhi + myreg->xy, yhi, zlo}}; } for (int i = 0; i < 8; ++i) reg.ptr->forward_transform(corners[i][0], corners[i][1], corners[i][2]); -#define DRAW_CYLINDER(i, j) \ - image->draw_cylinder(corners[i].data(), corners[j].data(), reg.color, reg.diameter, 3, 1.0) -#define DRAW_TRIANGLE(i, j, k) \ - image->draw_triangle(corners[i].data(), corners[j].data(), corners[k].data(), reg.color, opacity) +#define DRAW_CYLINDER(j, k) \ + image->draw_cylinder(corners[j].data(), corners[k].data(), reg.color, reg.diameter, 3, 1.0) +#define DRAW_TRIANGLE(j, k, l) \ + image->draw_triangle(corners[j].data(), corners[k].data(), corners[l].data(), reg.color, opacity) if (reg.style == FRAME) { DRAW_CYLINDER(0, 1); @@ -1907,21 +1921,29 @@ void DumpImage::create_image() // inconsistent style. should not happen. if (!myreg) continue; - length = myreg->hi - myreg->lo; radiuslo = myreg->radiuslo; radiushi = myreg->radiushi; if (myreg->axis == 'x') { xdir = 1.0; - lo = {myreg->lo, myreg->c1, myreg->c2}; - hi = {myreg->hi, myreg->c1, myreg->c2}; + double xlo = MAX(myreg->lo, domain->boxlo[0]); + double xhi = MIN(myreg->hi, domain->boxhi[0]); + length = xhi - xlo; + lo = {xlo, myreg->c1, myreg->c2}; + hi = {xhi, myreg->c1, myreg->c2}; } else if (myreg->axis == 'y') { ydir = 1.0; - lo = {myreg->c1, myreg->lo, myreg->c2}; - hi = {myreg->c1, myreg->hi, myreg->c2}; + double ylo = MAX(myreg->lo, domain->boxlo[1]); + double yhi = MIN(myreg->hi, domain->boxhi[1]); + length = yhi - ylo; + lo = {myreg->c1, ylo, myreg->c2}; + hi = {myreg->c1, yhi, myreg->c2}; } else { // myreg->axis == 'z' zdir = 1.0; - lo = {myreg->c1, myreg->c2, myreg->lo}; - hi = {myreg->c1, myreg->c2, myreg->hi}; + double zlo = MAX(myreg->lo, domain->boxlo[2]); + double zhi = MIN(myreg->hi, domain->boxhi[2]); + length = zhi - zlo; + lo = {myreg->c1, myreg->c2, zlo}; + hi = {myreg->c1, myreg->c2, zhi}; } } @@ -1936,16 +1958,25 @@ void DumpImage::create_image() radiushi = myreg->radius; if (myreg->axis == 'x') { xdir = 1.0; - lo = {myreg->lo, myreg->c1, myreg->c2}; - hi = {myreg->hi, myreg->c1, myreg->c2}; + double xlo = MAX(myreg->lo, domain->boxlo[0]); + double xhi = MIN(myreg->hi, domain->boxhi[0]); + length = xhi - xlo; + lo = {xlo, myreg->c1, myreg->c2}; + hi = {xhi, myreg->c1, myreg->c2}; } else if (myreg->axis == 'y') { ydir = 1.0; - lo = {myreg->c1, myreg->lo, myreg->c2}; - hi = {myreg->c1, myreg->hi, myreg->c2}; + double ylo = MAX(myreg->lo, domain->boxlo[1]); + double yhi = MIN(myreg->hi, domain->boxhi[1]); + length = yhi - ylo; + lo = {myreg->c1, ylo, myreg->c2}; + hi = {myreg->c1, yhi, myreg->c2}; } else { // myreg->axis == 'z' zdir = 1.0; - lo = {myreg->c1, myreg->c2, myreg->lo}; - hi = {myreg->c1, myreg->c2, myreg->hi}; + double zlo = MAX(myreg->lo, domain->boxlo[2]); + double zhi = MIN(myreg->hi, domain->boxhi[2]); + length = zhi - zlo; + lo = {myreg->c1, myreg->c2, zlo}; + hi = {myreg->c1, myreg->c2, zhi}; } } From 6e15c1d172520373c68f0de2e3e324577a08b0dc Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 27 Feb 2026 12:22:18 -0500 Subject: [PATCH 10/23] add color style "atom" to the body particle visualization --- doc/src/dump_image.rst | 49 ++++++++++++++++++++++--------------- src/GRAPHICS/dump_image.cpp | 43 ++++++++++++++++++++++---------- 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/doc/src/dump_image.rst b/doc/src/dump_image.rst index 689cd33c36a..6d98cde8e68 100644 --- a/doc/src/dump_image.rst +++ b/doc/src/dump_image.rst @@ -56,7 +56,7 @@ Syntax level = mesh refinement level, value between 1 (low resolution) and 6 (ultra high resolution) width = diameter of wireframe edges (distance units) (ignored for triangles) *body* = color bflag1 bflag2 - color = *type* or *index* + color = *type* or *index* or *atom* bflag1,bflag2 = 2 numeric flags to affect how bodies are drawn *compute* = computeID color cflag1 cflag2 computeID = ID of computes that generates objects to draw @@ -585,25 +585,34 @@ is used to define body particles with internal state body style. If this keyword is not used, such particles will be drawn as spheres, the same as if they were regular atoms. -The :doc:`Howto body ` page describes the body styles -LAMMPS currently supports, and provides more details as to the kind of -body particles they represent and how they are drawn by this dump -image command. For all the body styles, individual atoms can be -either a body particle or a usual point (non-body) particle. Non-body -particles will be drawn the same way they would be as a regular atom. -The *bflag1* and *bflag2* settings are numerical values which are -passed to the body style to affect how the drawing of a body particle -is done. See the :doc:`Howto body ` page for a -description of what these parameters mean for each body style. +The :doc:`Howto body ` page describes the body styles LAMMPS +currently supports, and provides more details as to the kind of body +particles they represent and how they are drawn by this dump image +command. For all the body styles, individual atoms can be either a body +particle or a usual point (non-body) particle. Non-body particles will +be drawn the same way they would be as a regular atom. The *bflag1* and +*bflag2* settings are numerical values which are passed to the body +style to affect how the drawing of a body particle is done. See the +:doc:`Howto body ` page for a description of what these +parameters mean for each body style. .. versionchanged:: 11Feb2026 -The there are currently two supported settings for the *color* value: -*type*, or *index*. With the *type* setting the body particles will be -colored according to the atom type of the particle. With the *index* -setting the coloring follows the body index instead. For both settings, -the value (type or index) is mapped to the colors of atom types. The -list of colors is by default as follows: + added *index* color style + +.. versionchanged:: TBD + + added *atom* color style + +The there are currently three supported settings for the *color* value: +*type*, *index*, or *atom*. With the *atom* setting, the color follows +the coloring selected for coloring atoms (including using color maps). +With the *type* setting the body particles will be colored according to +the atom type of the particle. With the *index* setting the coloring +follows the body index instead. For both settings, the value (type or +index) is mapped to the colors of atom types thus the coloring style for +atoms **must** be set to *type*. The list of colors is by default as +follows: * type 1 = red * type 2 = green @@ -614,9 +623,9 @@ list of colors is by default as follows: and repeats itself for types > 6. This list can by changed with the :doc:`dump_modify acolor ` command. If more different -colors than atom types are desired, the number of atom types must be -increased when using either the :doc:`create_box ` or the -:doc:`read_data ` command. +colors than atom types are desired, the *number of atom types* must be +*increased* correspondingly when using either the :doc:`create_box +` or the :doc:`read_data ` command. ---------- diff --git a/src/GRAPHICS/dump_image.cpp b/src/GRAPHICS/dump_image.cpp index f631ffa2028..9c5219728a2 100644 --- a/src/GRAPHICS/dump_image.cpp +++ b/src/GRAPHICS/dump_image.cpp @@ -294,11 +294,13 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : if (iarg+4 > narg) utils::missing_cmd_args(FLERR,"dump image body", error); bodyflag = YES; if (strcmp(arg[iarg+1],"type") == 0) bodycolor = TYPE; + else if (strcmp(arg[iarg+1],"atom") == 0) bodycolor = ATOM; else if (strcmp(arg[iarg+1],"index") == 0) bodycolor = INDEX; else - error->all(FLERR, iarg+1, "Dump image body only supports color by type or index"); - if (acolor != TYPE) - error->all(FLERR, iarg+1, "Must color atoms by type with body particles"); + error->all(FLERR, iarg+1, "Dump image body only supports color by type, atom, or index"); + if ((bodycolor != ATOM) && (acolor != TYPE)) + error->all(FLERR, iarg+1, + "Must color atoms by type with body particles colored by type or index"); bodyflag1 = utils::numeric(FLERR,arg[iarg+2],false,lmp); bodyflag2 = utils::numeric(FLERR,arg[iarg+3],false,lmp); iarg += 4; @@ -1332,6 +1334,18 @@ void DumpImage::create_image() } else if (bodycolor == INDEX) { itype = (body[j] % atom->ntypes) + 1; color = colortype[itype]; + } else if (bodycolor == ATOM) { + if (acolor == TYPE) { + itype = static_cast(buf[m]); + color = colortype[itype]; + } else if (acolor == ELEMENT) { + itype = static_cast(buf[m]); + color = colorelement[itype]; + } else if (acolor == ATTRIBUTE) { + color = image->map_value2color(0,buf[m]); + } else { + color = image->color2rgb("white"); + } } else { color = image->color2rgb("white"); } @@ -1344,8 +1358,12 @@ void DumpImage::create_image() image->draw_sphere(bodyarray[k],color,bodyarray[k][3],opacity); else if (bodyvec[k] == Graphics::LINE) image->draw_cylinder(&bodyarray[k][0],&bodyarray[k][3],color,bodyarray[k][6],3,opacity); - else if (bodyvec[k] == Graphics::TRI) + else if (bodyvec[k] == Graphics::TRI) { + // brighten flat surfaces a little bit + image->ambientColor[0] = image->ambientColor[1] = image->ambientColor[2] = 0.2; image->draw_triangle(&bodyarray[k][0],&bodyarray[k][3],&bodyarray[k][6],color,opacity); + image->ambientColor[0] = image->ambientColor[1] = image->ambientColor[2] = 0.0; + } } m += size_one; @@ -1846,15 +1864,14 @@ void DumpImage::create_image() double yhi = MIN(myreg->yhi, domain->boxhi[1]); double zhi = MIN(myreg->zhi, domain->boxhi[2]); - corners = cornerdata{ - vec3{xlo, ylo, zlo}, - vec3{xlo + myreg->xz, ylo + myreg->yz, zhi}, - vec3{xlo + myreg->xy + myreg->xz, yhi + myreg->yz, zhi}, - vec3{xlo + myreg->xy, yhi, zlo}, - vec3{xhi, ylo, zlo}, - vec3{xhi + myreg->xz, ylo + myreg->yz, zhi}, - vec3{xhi + myreg->xy + myreg->xz, yhi + myreg->yz, zhi}, - vec3{xhi + myreg->xy, yhi, zlo}}; + corners = cornerdata{vec3{xlo, ylo, zlo}, + vec3{xlo + myreg->xz, ylo + myreg->yz, zhi}, + vec3{xlo + myreg->xy + myreg->xz, yhi + myreg->yz, zhi}, + vec3{xlo + myreg->xy, yhi, zlo}, + vec3{xhi, ylo, zlo}, + vec3{xhi + myreg->xz, ylo + myreg->yz, zhi}, + vec3{xhi + myreg->xy + myreg->xz, yhi + myreg->yz, zhi}, + vec3{xhi + myreg->xy, yhi, zlo}}; } for (int i = 0; i < 8; ++i) From 7858b25eeb813787749f12227b202cb8545a89fb Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 27 Feb 2026 12:33:53 -0500 Subject: [PATCH 11/23] tweak lighting for triangles of body particles --- src/GRAPHICS/dump_image.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/GRAPHICS/dump_image.cpp b/src/GRAPHICS/dump_image.cpp index 9c5219728a2..133723d5ff3 100644 --- a/src/GRAPHICS/dump_image.cpp +++ b/src/GRAPHICS/dump_image.cpp @@ -1360,9 +1360,15 @@ void DumpImage::create_image() image->draw_cylinder(&bodyarray[k][0],&bodyarray[k][3],color,bodyarray[k][6],3,opacity); else if (bodyvec[k] == Graphics::TRI) { // brighten flat surfaces a little bit - image->ambientColor[0] = image->ambientColor[1] = image->ambientColor[2] = 0.2; + image->ambientColor[0] = image->ambientColor[1] = image->ambientColor[2] = 0.3; + image->keyLightColor[0] = image->keyLightColor[1] = image->keyLightColor[2] = 0.8; + image->fillLightColor[0] = image->fillLightColor[1] = image->fillLightColor[2] = 0.45; + image->backLightColor[0] = image->backLightColor[1] = image->backLightColor[2] = 0.8; image->draw_triangle(&bodyarray[k][0],&bodyarray[k][3],&bodyarray[k][6],color,opacity); image->ambientColor[0] = image->ambientColor[1] = image->ambientColor[2] = 0.0; + image->keyLightColor[0] = image->keyLightColor[1] = image->keyLightColor[2] = 0.9; + image->fillLightColor[0] = image->fillLightColor[1] = image->fillLightColor[2] = 0.45; + image->backLightColor[0] = image->backLightColor[1] = image->backLightColor[2] = 0.9; } } From f29e03e0e5c7a94025f9e7dba14c8ce1950fe181 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 27 Feb 2026 19:51:46 -0500 Subject: [PATCH 12/23] add support for entering colors as hex numbers --- doc/src/dump_image.rst | 18 +++++++++++++++--- src/GRAPHICS/dump_image.cpp | 24 ++++++++++++++++++------ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/doc/src/dump_image.rst b/doc/src/dump_image.rst index 6d98cde8e68..27d8279a2db 100644 --- a/doc/src/dump_image.rst +++ b/doc/src/dump_image.rst @@ -181,9 +181,10 @@ Syntax color = name of color for simulation box lines and processor subdomain lines *subboxtrans* arg = transparency transparency = transparency for simulation subbox lines (value between 0 (invisible) and 1 (fully opaque)) - *color* args = name R G B + *color* args = name R G B *or* name hex name = name of color R,G,B = red/green/blue numeric values from 0.0 to 1.0 + hex = 24-bit RGB color in hexadecimal *ccolor* args = computeID color computeID = ID of the compute color = name of color for image objects provided by this compute when using "const" color style @@ -218,6 +219,7 @@ Examples labelmap atom 1 C 2 H 3 O 4 N dump_modify 1 acolor C gray acolor H white acolor O red acolor N blue + dump_modify 1 color gray80 0.8 0.8 0.8 color gray20 0x333333 Description """"""""""" @@ -1134,12 +1136,22 @@ dump_modify color option. ---------- +.. versionchanged:: TBD + + add support for entering colors in hexadecimal + The *color* keyword allows definition of a new color name, in addition to the 140-predefined colors (see below), and associates three red/green/blue RGB values with that color name. The color name can then be used with any other dump_modify keyword that takes a color -name as a value. The RGB values should each be floating point values -between 0.0 and 1.0 inclusive. +name as a value. The RGB values should be either specified as three +floating point values between 0.0 and 1.0 inclusive or as a single +24-bit hexadecimal number. The following two commands are equivalent. + +.. code-block:: LAMMPS + + dump_modify 1 color mygray 0.431 0.498 0.502 + dump_modify 1 color mygray 0x6e7f80 When a color name is converted to RGB values, the user-defined color names are searched first, then the 140 pre-defined color names. This diff --git a/src/GRAPHICS/dump_image.cpp b/src/GRAPHICS/dump_image.cpp index 133723d5ff3..57115fd4648 100644 --- a/src/GRAPHICS/dump_image.cpp +++ b/src/GRAPHICS/dump_image.cpp @@ -2582,12 +2582,24 @@ int DumpImage::modify_param(int narg, char **arg) } if (strcmp(arg[0],"color") == 0) { - if (narg < 5) utils::missing_cmd_args(FLERR, "dump_modify color", error); - int flag = image->addcolor(arg[1],utils::numeric(FLERR,arg[2],false,lmp), - utils::numeric(FLERR,arg[3],false,lmp), - utils::numeric(FLERR,arg[4],false,lmp)); - if (flag) error->all(FLERR, argoff + 1 + flag, "Incorrect dump_modify color command"); - return 5; + if (narg < 3) utils::missing_cmd_args(FLERR, "dump_modify color", error); + if (utils::strmatch(arg[2], "^0x[0-9a-fA-F]+$")) { + char *ptr = nullptr; + auto val = strtol(arg[2], &ptr, 16); + double rval = ((val & 0xff0000) >> 16) / 255.0; + double gval = ((val & 0x00ff00) >> 8) / 255.0; + double bval = (val & 0x0000ff) / 255.0; + int flag = image->addcolor(arg[1], rval, gval, bval); + if (flag) error->all(FLERR, argoff + 1 + flag, "Incorrect dump_modify color command"); + return 3; + } else { + if (narg < 5) utils::missing_cmd_args(FLERR, "dump_modify color", error); + int flag = image->addcolor(arg[1],utils::numeric(FLERR,arg[2],false,lmp), + utils::numeric(FLERR,arg[3],false,lmp), + utils::numeric(FLERR,arg[4],false,lmp)); + if (flag) error->all(FLERR, argoff + 1 + flag, "Incorrect dump_modify color command"); + return 5; + } } if (strcmp(arg[0],"ccolor") == 0) { From 6e4e4f12cb9e3cd97272d82e3417910e2f494e15 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 28 Feb 2026 09:46:44 -0500 Subject: [PATCH 13/23] add missing references --- doc/src/Packages_details.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/src/Packages_details.rst b/doc/src/Packages_details.rst index c21e14cb6c8..8e2636b2f8a 100644 --- a/doc/src/Packages_details.rst +++ b/doc/src/Packages_details.rst @@ -263,6 +263,8 @@ particle models including ellipsoids, 2d lines, and 3d triangles. * :doc:`pair_style gayberne ` * :doc:`pair_style resquared ` * :doc:`pair_style ylz ` +* :doc:`pair_style line/lj ` +* :doc:`pair_style tri/lj ` * `doc/PDF/pair_gayberne_extra.pdf `_ * `doc/PDF/pair_resquared_extra.pdf `_ * ``examples/ASPHERE`` From 7cb64691568808b4ddb57a163bf9396021866f6b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 28 Feb 2026 09:46:57 -0500 Subject: [PATCH 14/23] improve error message --- src/random_mars.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/random_mars.cpp b/src/random_mars.cpp index fb6fddc1eea..da646401234 100644 --- a/src/random_mars.cpp +++ b/src/random_mars.cpp @@ -36,7 +36,7 @@ RanMars::RanMars(LAMMPS *lmp, int seed) : Pointers(lmp), double s,t; if (seed <= 0 || seed > 900000000) - error->one(FLERR, Error::NOLASTLINE, "Invalid seed for Marsaglia random # generator"); + error->one(FLERR, Error::NOLASTLINE, "Invalid seed {} for the Marsaglia random # generator", seed); save = 0; u = new double[97+1]; From dc41a502d239caaccd4607d3b7303693e3b3720d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 2 Mar 2026 17:46:52 -0500 Subject: [PATCH 15/23] improve visualization now that we have a smarter selection --- examples/GRAPHICS/in.peptide-hbonds | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/GRAPHICS/in.peptide-hbonds b/examples/GRAPHICS/in.peptide-hbonds index 37b1752f297..6c7c22953c6 100644 --- a/examples/GRAPHICS/in.peptide-hbonds +++ b/examples/GRAPHICS/in.peptide-hbonds @@ -62,14 +62,14 @@ fix label all graphics/labels ${vizsteps} text " Hydrogen bonds donated: $(c_hb text "Hydrogen bonds accepted: $(c_hb2:%02.0f)" 210 30 0.0 & size 24 backcolor darkgray # create colored arrows to go with text labels -fix obj all graphics/objects ${vizsteps} arrow 5 80.0 61.0 39 80.0 67.0 39 0.3 0.2 & - arrow 6 80.0 61.0 37.2 80.0 67.0 37.2 0.3 0.2 +fix obj all graphics/objects ${vizsteps} arrow 5 80.0 57.0 35.0 80.0 66.0 35.0 0.3 0.2 & + arrow 6 80.0 57.0 33.5 80.0 66.0 33.5 0.3 0.2 # combine the graphics into visualization dump viz viz image ${vizsteps} hbonds-*.ppm element element size 800 800 zoom 2.1 view 80 0 bond atom 0.3& - fsaa yes ssao yes 12384 0.6 shiny 0.1 box no 0.1 center s 0.5 0.52 0.52 & + fsaa yes ssao yes 12384 0.6 shiny 0.1 box no 0.1 center s 0.65 0.49 0.42 & compute hb1 const -0.4 0.3 compute hb2 const -0.4 0.3 & - fix label const 1 0 fix obj type 0.0 0.0 fix graphics element 1 0.1 + fix label const 1 0 fix obj type 0.0 0.0 dump_modify viz pad 5 boxcolor white backcolor darkgray backcolor2 silver & element C C O H N C C C O H H S O H ccolor hb1 cyan ccolor hb2 magenta From 8f09a286a2d8b58bdb504937594c23b68f4caf22 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 2 Mar 2026 18:18:28 -0500 Subject: [PATCH 16/23] improve peptide example with added imported image showing hbond definition --- examples/GRAPHICS/README | 3 ++- examples/GRAPHICS/hbond-diagram.tga | Bin 0 -> 134647 bytes examples/GRAPHICS/in.peptide-hbonds | 16 +++++++++------- 3 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 examples/GRAPHICS/hbond-diagram.tga diff --git a/examples/GRAPHICS/README b/examples/GRAPHICS/README index 1779b4af2e6..7f4024f3cf1 100644 --- a/examples/GRAPHICS/README +++ b/examples/GRAPHICS/README @@ -21,7 +21,8 @@ Here is a list of the inputs and which graphics features they demonstrate - in.peptide-hbonds: peptide with surrounding water molecules visualize donated and accepted hydrogen bonds - https://youtube.com/shorts/1QEjIITapwQ + overlay graphics from image without background + https://youtube.com/shorts/Q6KBE08AG8c - in.obstacle-lines trajectory lines with obstacle flow example https://youtu.be/9HEsGaOsdik diff --git a/examples/GRAPHICS/hbond-diagram.tga b/examples/GRAPHICS/hbond-diagram.tga new file mode 100644 index 0000000000000000000000000000000000000000..aa91f6a2c6d16302bebe920f4f129dd56e4321ca GIT binary patch literal 134647 zcmc${NwY3ld7fRT3O+}CBM&_I!V`xhH1O0O_z(C8c;dg{nFk(u;Mt*Q4t?JUD2}S2 z=&C4$=q1n*ecyLNNR$wr=!^g%2_aP9b=~x)@BjTNjNSF-H^13=d;INx;p61@&0_i$ z&Nu$zFa82CHxYRQbHOR4u~4Gz;~Y=MESMt&Ll@&ejqoQOwEX+m zWAO>a(mu%XBqT33BMY0quGq=uOy2nOjcd?nGy;@H2wG=4yq zco*%^G@q|+*pPs-)b+X^S5BB6KwZ!=xbbt<6eH!3~2D-PZ>Tdq0XqV#QAdAYVK2hJFc%O zwy%^E&@8bS>EN;`_xFsIa`XY{%T#WOze~#Qvwu65MuqJa95c3&u|>Kf*1T%PaV(mKp2psotoUF5OY;N52g-i-+wN$GJvBCb^KFvPN|;QODx{_&7Zi zN}H9VtOuPJh|XEHaR+Ez5JXq#^6kgX$;x7TDuBIsQk1Sx?&cT(!SGXhzmGAMz+G1;@ik{&pN;kV zpNkatN64Z9osWIM5#YxOSBU@8E&_ zvILP*So6H|l=^}i4RZH!{-`sr!9$sUCk+-7ypczmSZm0qqFD>Jp$78G>>c?xWplf0TzZ zeplFfFvd939&`xwsCG zzhSeZXB$>WF2|7&T$6wf}V)`f~!^Q$U~ za_^!b(Q~1_fu6$*w9<$Xniz9R%b{>a5mI>v+t*!(fzpy2ph;~EYp^W@vpOM$s@2x- zV0%A&jH07FzQ_FUNV8XXG|6dtmzv=Qs!L zeRPMbwDzbqdgKP7Kcf|P!pKn6*=h6*0lQ~10 zzJSrIaDM)^IB2hXe!0e^^CWt)%$D+%QBr$QhrzXZH+?N8N_7vjkJ3vWMI1s~wOXAR zIBU=3>biXX44OZcZWrxWFnSf*&$t!`?e*s7F6va9G?c7Y$?SyoT{xef3(YJ&&OsZ$ zI#Qg6;(ZJaAn(ca25*&lB?oQ%iWFE7JI}+|C&X*4?1$71rX6OWI3Lq1@>v&GgV!=7 zwA9UvV!}osd-r%P21@**tYJn;Y}P}`c<|zAZ9EuQTQ8K?;qfJ?bJK%t%!%xCoZrX{ z%W>l|sMV5x#S4``%s^{%qk1A5EB-_BTQcgI<%JEY-q{RNuV$c~pOXk?R45HH8tF-U z3x8{9Op%uERh(KYJ9we}@KYlN5jZ5qI~f|1YO5^$if4l%os`Y)?uA;CAG3X#<2t1`(@UyJ%^f+wD0owIQ7Swod+q~ zL2-xSRUR2TxR#MLx3yyw4bABU)Y@iT+{L25VV|XEl(%vB?Pl#bwYL3?F~wRhB8xI_p3WRc!BcqY}7Y!tSqd;fkHJNVgoEyHL+M^_)i5Nn?`TWR!42j>V>l?00X*))$ls}Lo zhHP;Bu|o)-m7qJ#z&uE*B=4qHKMfFhe_;e-P9$ykDP^Z!d^xH1{C;t4um_I0d4j{7 z22iA#DnmMqyWg2qdz7^0r=QusjVdE)oscuS8>C8kE5{DUpF6bS@rdD1r{ac-XHq3S zBD)Q+e?k8aG>oJrY>$y@&s#WlIR28MEhQp`KZ1XdRC|=P1<~Kzf4QIbT)aW5l!x~@ z{=<$Ebf;b7;+a%Q4{>Zk^eg&zpotj%1da_qZIEiuoA){XnxQQv=uT6~9c5-xrz&Zy zQm4L2j@y;=pB=g+pRPfwB%coY(7dbBP`?;CLkE}GHMTc!ahzJ!@-(u` z_E7rddXqzUrRY#_?HilYR{XD^RaWLVzhRw{=e_bOpLw=#Y!7m=>T(6GHboXXKjY)e z=YFQO@2RrGYZ(UXjr)YxIpta$l=*t8+K$OXPh+gSqgIjf;}j#$RA|T6G^WJcjvu5| zmX5F#RRD~)NQ^x8Y!2^VqRK|_+;=^4ExXM1imSqy$RTp+IcrMXi<}K|B|abt%EyS| zzE-}^b*w6$xY;+hS8;KaR?8x5NVq8S7M6;n2bZ$tGOjy*drvjMVv)8HuWZRU5OU=7;J z?8`i)xGS7IlWW;op_syO4#AB&b6FH`kSp=k9BZwZYV%o+O(6(bzMF8AR?8v_8CiS) zb*eLC5iztBF}9S1iR)iWeM1* z-eiH|E*WMtOXVd~HaKWs9JQn8ZN@EIdp2fq-Wi{1m1PWGqG3pSncP_G-FjSuT+0&m ztVXebWsk14WyNAO&e*gnJ1IMzgS4xx-o{K-IkGM>EnB&RwA%Cv4y#{uhfaOFWq)&t zUD>D}q+Mn0=oVR**!6Uj>b<@CwvL`>T5U=l-O(+(;Y;j#8uWXZ%(Sbl9lJ9B61$$N ztb?@L^s-BI^WLIYU$c$Nvvx06dv?vVtE}4M&6sCCrNy}MZJViTEB7giJ5H`;S*!QC z=GM2i7h4A2RN`^+RpJgy?|?61$LM1>IF3_mUUo41I=XGY%!ilgGn1~;b`*R_QTv+o zW0F*cDVjD&wJY1neU5o{)&Vi??0<8)GBfEat!_!@Xvh<=o%D~WgLKMyk*akHPjQ}y zshz&lKH}HcpcA>s>1ASCM)K^i?Ll{@uPt&8(yek@XY5)T@gh${du+1x9~oau)fIHw zl6@!J)vaamZSrcJr*i%)#}3l1a(eSH`5tPZExq5 zPlqCB!X^)Q57LR*3*?0zTZtDr9S2iV{{1!RRyn;4PPY~BkXP$WJaD)-ob1qd zeDF@jeJT@MsT`{iUi{LrgLGmRIgQO!ULvO|lkzUeIY_t4=`uF?`d#V_URyB|dk)em zCr?=5A8e+af46cvcBlOLg<}Wl#4K`lcty?*ugEz_x5_DOHnt4!QSF9jDm_1U>^P|w z<#E_f6?w1hc0B$w#}3l1ayo*i>JvFT5ga)O=~g*A8EM+A)o04&zj5p!otQnx`8(Ao za(2dkdJVc&&Q8UA-z7Rn&Otim2k%$Tjt_p~*g-lmi=1B3rs@+pJ24eG2kBNh zJ8AOA>b##OKX&*ysTMs;lAZj&<5+7xMgEVjLAT23jGXFO{U{SJCO4JX&aMrl^aYj=BlcA1LP_ z-72Sbo+``-<<%8t@=xR(q+8{X-CI8RkaBj$B4=l8rd#Fg=$!ej^W>kuzQopu zRumu7`paFwPPIXqr`0gILm9Qm`|}k=XNC1iid;D@-$6U5(Q3hthy8H=Ty5S)-#s9P zvrx+|GaWuGMLR!LRbLOjDJfb$g)Sc=Jgu(pC17X3={-AfVMu`VIO41bj)n+L_T zL&`1@k-1LC8U!*a-!j`#63d7{P(|eDn0-V|fr})#Wd5{gh*|K=7^pElALH>WDg6iw zoD*s6VmhhN4SbD99lOjm3PrjdJVs|;BgU-rCzjCW-Xew-L;(*zBavW6_j0tqK~(C0 z8e)f!n6yFwxS3y(0gJSc^LI|j*VA|U0VK2M^mBEsVpPT!`Rlmk7&`U1c#N-a5SLgY z#7+-fKsruwOtB0zc@SGFf1+rQn6a7-YEcbYkgqMgP(NdpseatS(A6qE1*su#FB&i@ zN;8_ef|mNTW4?`wK?uuS@NnrjE^;I_?BqZmaXtPxLVz7MwM?G>uGseuK~ z(szrQ8c~|se?Nym4O7U}&m^K+%wnK@qk3-Mh}qM7G~H8?YJ-dFEFJEVJwDka#B1iy!TGjrV)f9le~n@;*MQl2Q7?RByA# z+>04VxfdFDE-{me*mFlS-Q`R^U4+s9*c}dY;fUI+nQh7x>7N>S@p5^e85h>{Q&I9+ zkBQh$iKXb&+K-mLl)1G)WfLgTphEVjJ>6-s ztkbY~E7)*QsZ*u#J&rDzZe(Iv`){&L-`4Mx;?Y_dd|Wiz_q$9o+d+pJL7>v&4;6J# z;nl!$52S1R46iJPNjVI1ppDZ(H;{`ZzQNa)nR{zgPF9&;^;^0WB7Bjr4`867(+pn4 z>-y<~#K36M0TowsP&aC$A{^HilaM}Ekv1tI!Wd#kXX%WnGMVGjp{7vuuVbhny={x{ zTA%h5Svf~@4yw4CG^q{qw3syU(xh6}we(aqe5at*i?8tCmT|oUDC17QS~+fJbo?p9 z6jVDs^-2&PRCzTKc;cA~Hu>0M;^6&+J{6m3_;(PTqDXH{A~&83@m@F@b#8J9@LQ;U z4`*VLZ0e<;_!tYjD_pAM0j=A@)R3wZ@J)+#Q@SP%(4|?reu!AK<84#R#U1GXgdVw!UHL6eX|_K-zN#!BkX8f{MqFIPrj{ zt5pa|L4gINYl~&m*y|WQ-P@+5P{Pyqb;c*^6sgd-$F^O56qdMoTTa)TzfVwZq+=fURd6n4- zeCRt)abLyhC!BRa=heO{_Hu@FZLtptNz>x}MnRa=WTro>?5!+3M*L8;ZUSjD3jB79u}{f09u_h>ZE9j1gLsD;D3a{JZ7OwCk%8@XF+2? zvz7D>j2>571jb8_QbnzYtq&N{~yjiJdHYT5TOj)vIW?v=tZWsiI!S2IeF z$Q}6UE}u%TA0jCI=t}z{f5Q(`?YK<#pD{l3ndNIh^IK)NK2-;mV^j9}HdyI@rTmH4 zmi&?Dssp}NuL!O`Us8TY5?;6aO8EmHKbty6p|+3wR@vB=d1SpZxeDt8=B>s;F`BWpN%_?EfP zg1qgVU;F&LeUe3xdh8tQkoSCf4c!Z+pY(IQ_1m)X%Z%4QqQYBlaeR(IA)pq%M0HJ);XS4^FMOk7B=drW)~y*t%dw2 zE{s7e+@DXc`xbcAs2e7}ypo?M@5irI{=5`k)BTMzh=J z&;d%|CL~bWcl}+w1Wz>PE>J{Z{`CZBuCzoxcSFP_^RrPWH4{?w`fNNBF4z>SCvZo5 zb^!Jtw3QEi^yJewbjg1mLOfSW+e24i}J4uU>afq$T*krMN=|k26ZrF2UPzXppNgX08#%Lm^kCN z*f201P+|R=2`Ftzu*f|@J7vC15MU5 z=BmE9NB8Nvo|fmIcrAE4D;&7Ytta9WM{p2qxfa!c%N%Kz2O}?>P`$zCWxDVrGg2n} z_mG`whL34-6VkkuB#UCzm1lH!_^L6TuD%Y2t&HmU-Y?(Nld&lF0Rc185iQ> zVfx%oVi2-#p`;ryXWG8akw~Wh^j~e!^C1TY5S+Z`IEp1A2&EVU)G?;7E9lGK1fo$V zivv@TDv5=neTcyBLN^&{h%*R)h(=_hpj9a*%1f4BiREt@1=+kIoG4VaK&QQQB?{03 z%?%7u!TSLY?Sl#-6qGoR(*zC$Nv&;Rib_opmts+0U+MB|(5g+Af~G;0 z*U@*j(&x$hQktA^`yPiYy*v85IYUl(NI7m}oTy2AAs?x@6nw5x2Ij^v~FCI<)75O&9YWhkC2o`_0wbjxsdMy-i0X zJg#)*HE0pNxUyC(e<$f|MbC`{&^gieeU5_58;G<2`kkMTnvB$w@Qx?3 zI$srz(kVZ+u!1F@u_73;7OvhV7z56-{fNWLl7IV7tnd;#Y39$w#0?C`4c2kyL?>Ra zZm8F~u%m5t1ATErEk~|`TW;91bB@$GA?`w-;EevfTz!x|S|=L%tv=v&e8Bw3pt&Wb1SXgtv+Y_Q_Rav83bEZ0}) zdy-*A0B?#wBfjg64U0FuQP%o#4MlQ{YQM3r>;0|Yu>8HMp8bJvgIbnY%4LG&(gwjH+1<2(Pn> z$8w>QGX^~CzN22dvq`>=p5%4*9bMkAF0eq;TSf1unrD`ug8Xdjhfde<3WP$a*ei0X26NzsGdxnuLmE-$30H}n#uHKtYr}gTmHWcT(PRAis8?Y5q60KHwK!FPtH_k-dVPy_Jue&KpWneD#UI@zjCR#C-}c4ZEtG?een_K;LOf)H%!~S^{jv!mAMX zFCGi{{X#4>zMNxU`dvlUCl^1>YJ?s z4A?%Efkl2=Rx$TH^2j4};U*BgQ|OIL{uA{&s|TKVNTK8eHldQ4Q9{)!)-o6uV`X5| zwa%eGnJpFbf+&i@xdyN(g|`xiSGpuZ zoDJiPF8Mhk<8{Fcn|=cr(yZsXG{HK^MS{EK4#oXx+~dX(D@{PQM30Do-bO8>X@s@LA@Oq{DsLaKtH z-ga*&L8OzjWAVtuNUWeWgkY06Mn9FP8&_xf$(tt=NzC91v1DSq#hj;eT)+}&N8Hr0 z)^0i&U3qYa7J&-ITfXo4-vkNIx$RLe^vttn5J|DcjJ0)P?X~q$SQaV2?W-SFv;0uM-FaT6;^4YN;AN9hUGYITq)9 zu8gx`diiXBW~GtjCG*dM!P}<05ziFVf1u33XHLvpF1W+bb$O3v-#0m|V@~y%A%sB8 zpqxgZMrBkCj1UA~2y)F?=JjDkKRjph#ddrORd)qo@-x?P@j6g72#{qN!Uj`NM_mNu z%uVNjT*pnSSgOjg*r3*_shZ0i79Om$88{G-=A~%i4@;JIjy!YqW6N&%1d`I+{%N} zruG6etPMfy9+o5uw|g07&M;TRM9n1D}2uZOUB`h-aVMvv^fl`FGy#n8P({Hc3Mz{rFiXnWA(C-BhH}`65IWv#T=x+4g zhMk___j`|kPXF?|wV06~fGY;yQ2K(Qvrh}5JN|GjyHltzDxnXg4A+&{Bq}C*eR|6(KtPGfWomY5%=he?QeURQzTt~7I7_gO@^J-m zpN^p9A?)cn`-d5?lpV+*m02$nGR^?##DqI4#^)eupFVe?bn4kcnGXa&8-ojs_?_43 zLrRbN7E8U+jZScmjo7;2;kNve;f8?84bMty)I41nF-4*TI`3=&%_kBj_2Wboib(*SGuM92Evmy*WyjZL z1|z;nXe=*A3HEqDlK0vMBmFd18F>w0lf1Yoz@i~c(z3u8M)%WGs}*qo9xmxdi8Es& ziI}CX`uz6W@U4^6f+Z(Q=;-3C?F4_8Sk5v{-w$dRuG)U|yb86lY%H-;S}x3*Lj#W1e|;6HFvS+JzhiR zBLZHo9}7#|5ia&=!aX2O7*YXI@7;8CjdDV^p^VQEjN<$)UmWXalckQ>9w^JJMeb+6$SI2PUwrVj{I0R=1)Z2=+yzF1^Ft zaaD1it53e$GR(O{-^j1A!Rs*)>C9N$mw7ez_czq@G-v=Wq7U#;oX5zsg>A|roFl8^ z#JK{075%m4P^%*cFSI__mNVcX594?I>a=}=>sCFPR@rC&D(ea!ZP)r?umKnOMCK5b z@fR58PIAb{_zRoIu#(<3^02fha|~eTbjw_H)*tpo9(*HjNP@^4lA!55k33d+%7ARbzN2bHXe# zvB{lL&x^bR^sB6j4`Z`=c>W?s@~SZWL$2NZ=ZV@-7jo}$fX6Bi9$WePh2lSsMJBfN zQ#_`mMdm?1%Jpy`wiVxz+xpjP7rEdXxttfN<;#P7R=Mr7+CMd~$R%Fd&y8=MEe{LJ zS*~2d!>vs0oZ|9K-V}$8Z|*UMWg++;uG4$GEiF7rE#cxfR#;pT+PMd{(*S%NVQju_-tGRqx)*wQoh|Y3)$IBJ%(b<#~)e zxlH>Uf7dmoax(JpUE~eEFpiG!XnA{UN@N!1D$$tcErOwj#J-(1W#r-ggfiDPWxz=O znLEWqW18m&g|l-bvt#WFKC9g3J=OTgopPYDjodkY4)R&$Zq(?=Z2gg~O_7NoBXiI( zwjSWI%IiF-8YgetXF2BDnEg1ubWfZ~{E57SJXV=IHTpBkoW>#(43+7&zU4k=V{VVl ze3a`k+jBO*ZKzm{T;?C&H6wBdKC9gJ-4Gk{%lyGtjjsf0kcTHacNhxm|B?CcmRpGPLP`#i}xw!~8V{|X*H>{G5!AEM(B z8}j<3WAI4+RgN^a`MOx;uXBU#K|ZV8_QkM%$m_2qkpy*G&^ah#RcR+G zJ_g5ir&XSgcc?_7Qt#3-E3r(S@IJZTnG4+L7p?enS=h{iRLo<>qj_ciWMmXWNgrSO zV6e35hh?60d?}2mf4pu4-#-8ES-OD?IRqUv4-e8>!rd%8lV~wx-__+TSvR0o+jW9N>e+Jx%SeP7VS0y&i|bUFpe;9 zT}gmXZo|Xp{#>ry0$b(rxDj$}7PKmcpm+pn&g+)>jYql0So4!W*e-c;6AgVhtG>8; z4*Y}6eI6c^@JYB%KL2n_gC8%Ke>>G4Apd+Adjn0-&0$-xIKXZd-Rxkqa9I9+h|`+t zwPE?d*hj)8Acl$**$4S4-(xR8A|F@-3$mEHm|uNf+wS8y%43ze0Rkvq(f+=G0q+p)Ft zVW>H)+{UfeiO4P7onw1|V_h?@;GxW{7wxBM9geNU%ouBt*>OC~f30#4@>%7=XZ96r zmIq~B?}&B#T!xL;c@2o%gM55&8ha<+^0(yy-NY+$JN_73Wmv2B$0B!%&&ch{F|4p}RL6sSlmbx1NcXAxf3|Rt|4NJBh1MH$NMzJ6|~oEp(xKL(T{ z`XHZGE|%S5CD5bF>-H92l+`0Bik?eI#2#m(WDh^g7*<25(*2l{`-6dot$ne$vuE(n z!_Ga(=OxUITrAzPIJ}S-ohs%dx8oNR)y0;%2l*)1V^7aBua&(YtNHW({gG?%@#_we zyQAlu#B_@V9`_27+XZw;rhJ&G*On{zta6zrKGtqv zRb;obkQ+_zOsYQTNAz)4qNxVs-fr4*Ce7h^!SIb_Qu;MmDLwvd_TWp`+N|%s`3WQm zozm=6bgv;lEbG#`j7HO|S^1>5pE3t|JT`D+bXim@*apW$0cOwn^?nto+prslxUD*L zWTC!-yJZJ6jYaxKmPPtBcaP6)20VmubSzzI?u>OLMg)1z_M2H-?}p~#?{QW>hrP`) zhRRT;7+JRFlP@EEBi-&?kCoE%B$$d3+lSSFq4lmaW0hJFy^(Hz!h8Wa!pBu9E7N|2 zEv-%?!=USNxbFJY;(jYW-o?QeqwlmVZYL^!Aj{K-o*x2 z&RnkT*}U>uP{vTfff$a+h#s)Y^Rt6|-1?5&-;KM1XDRw(yhS=?FR<4G4z!+nZfACV3&%1!Wb zR^DhSeUwnqOmCVBtm{-M7wH&0Cz;Z(!Aj{K8WOCAu%&zXsNCcWMVE*;e9*Qx%|}?h z0X80EJWa^oTas#383Hoq1Nxk5y~DEK>4zAun$-4m_>Mmcq&^G|6ONMECMC;Ge?Zv3CWZH^E1_x)OlHeh6d5SY`6z zzp^f38}(tXVh^%Wsz(Rhrwfz8Te?|AV=n_kU?5POw>;7DQ&xu{%2jt_C zV~ksm+8{@jfzz*)i@!;l3?cU~?cz+(MM3O`;5({<$UuT>T&AhYao!Iz+hZpV{$6G< zZ__~H(dt4Qzw9RJs4HCa+X-|n|8cyE+7x3OynSfwu@f18=g<%tk8)kw`CYBzFI=mS zsz%VYe6?^pR%XVJFx_J-R(@&!5GzFGqjrIZpJ}Y0JVdU)KUhE6fiv@YN6tOHcSm$V zo%R*}9+cP$?l}4va2kUMZ61|5YDW)zhEt#JEY2WmugHGWS-3MnH6)0t9hdc1W_#=e z)z4&h9#rueaor!k1f^%nfUc;<^Z z5v|dVvws4oDX@&S4y-7ELh%ubL^^*|;5bL0=jNF%UcN6L!zwtlq$f-2CM`IPixsCLB zjI0@jWq#F(2x1vyj&LcyHv@4U6X{NiOS#q&mzm*%=sb)@Lgr#eu~_~~R&AZinYS6c z2mDEJ81v$3bm&z?`F;5M$+TDkWq(TDo#^PkWB?>uswIA?7LYXJ25{(DdV>SAl%Y%3 z+1L#bkp~qc79G`s9?f`>o$*FQC;5+=+Q^IvFo5%YmBOLf;1Tinajj$N!h)oB!6W=G zx&F=yUCd*`5oA(I5vifBPrw547Ans4m)e+=U*|z0su-H0t};g15;?g?W#WAE;Tm$# z)^{@1!_12PxPZ&F@A7xWh5lD_?Jo^s2SW4x08~moGa4Ag%hJd>z8tB$LTsMJdp(@OwiN3R{tavh;f0@FlbAH{05CsMZF=UJMztD!zwrn82Ku-h`c)_?-kJ za|WLuA+6^cHg=3D2iKpZmA`7rWwbzd+CsTnO!J|Zt>t+LZUgnSp?`cFQvsUjkyvw zNF<$b*o6&1&OFf9_%fR+VjX~Bs+NAQ2Ay^G`qmq&ahWz%sH;JEFJvD5tYe~Z|24t( z61pzNK02XBDp(^2T+fj+%3lRr(vKJp4$Kc9Ebi+uJ@Xn_86$`y1B`M_1U*-k&)o_~ zCcIc>7)YoAGM8!Jw-WgnB zwKN_(({rnaumBr(1-0f!0e@O3N`bl%j*pw!2YbKM3%03650_=U_=lz<~^A>XzOLzWOLsY z7V1OzApXV7^+`>3BFLdDuog%vpNJW}ZT>t7QBZ;#dTrpeVYnFG(HblbPSA6i_67c~ zI4#ad;xHv43?fuNcbr0(+l~dKL$DNll3oQ%etU!Yye=qKkRL@?#a$bB*u+yENzmWAr22G=544;b3uncu| z3qSzIyfl{~^`%RXoqpB3F(S-rYJSG(qQ!s0u*VKepD6(#e+vP%BQmIKxx_Vto*6(N z#1a%YQOo=N%b>bW?P-`?2{(5&XSH}R{X1nKZnaX~Kxy*K5^ycEKLCM8p_pVFqV-eL z5P|zDyHErmI-ZDpWWSODbDfl67`*^k)eb>LipElMAvMKphF@2|yhdVg*|Wi7PUb>m zu1=dB!UZ)lkqL=16k=Xl;6rb^lCc<;`)6#Y>i`TNgpJ1t+~A&1TpW5$b%Bi9_$Ur( zK7Y|;`0ql2LaFQk%g{3rFfV`&1?vJ}MHdW^CVy$%uY&iWMD}6K4oaMvl$N_RW>-eI zYgEW_n?J;C5BJ}ujfFd$`SUT3iPQabP4^y)8!NneuXq+x=z9UBvfTUham;YKfRe6P zHO_{SYfkSgy;D@5rL=dr!-T#p&csSEBf^-P=7SV>1YmVbwpgCK=VJ(b7-|oJ3SbBe zTmF1x?8l!Ea$OI6q8iH3Yp^@fz<@aBSCFjz>V=sjG=Zg|KzPQO6KJ+z1A>ep@+@}qkki{DA4nVlK~QF3=t@iEHIV3;4KMic60B0=7rkOU z!ebD6^xEWggO>duKxPaMj>WOCO1!|T=`wc$EpxFsGEia!-?&zXv97M(be-P1U&{kw ztYe~}xsIW_A-m#+ngN18GZr7E&%=~Rpbc|f5Y~QFeu(SyG%&iJ>MZ2PAW<%=3!pVH zRFMEhR0WIzQC`uSdAq<>1dD@ms%}IyMn@HZ6tqAhx<{SEZO0Hb|l70A+rgOUuW8GBJX@DW4d zfZsJztqeJs&SfrRoy%w*X^;$NIr;*K_R*eE65kv~Td&0>_ZMYadgkZXSk2 z06)&rAvS@So9Jf78F=2t?9=j|N8{)kosk|Cu*CpSH_mMtsKBvHI)(7e4uZLd)tq*n49esqs&b~;>;Bc(tO-h z?@;>2k*Si^ypr~6RhJz9IHM6(Erd55&c*JY!6uJJ-3I(4>1t_{IR}IIAhx00zGN@m={{4`mABTd?O3}R6QFy)Q!97 zYtk?B!V-ZoFVT~r=EJb#f_#jWM@b;uzCup(e+w_xG6w{p=TJ&(spfsLz}-?lXUA=y z=co+J59WfQQ8ub}xgZ(j`5)5~b;I<8FA4-Q^hSGTFJEaI^@1dj4W!Wvv;jJLG30G| zZ}L3L%C;dzg#^8)PfP3@7}7%gF{yT2qEhVxzTSW=F#=9_(MLs=Rb~Zjv}%Us19;>! z=NHAPU!JozK=8p}32YB?7{0hOEMZ;n{T?G{Ix;lFm&8UZhWt-}PQP7b;dVrp%9&SP z?rVESPuc_gb>YrRfE+v1SMd3`Z-s9_Bej@0s-S8Zc)wGzJuAY=(3RsL#meWgPA9Ae z=C>ItsC$K?XZdo=s8>UV4;{CCila6huTn1-shHDxT`B0RFz~3Vxq-7WQa+7#kc}CjLWnxyeOQ1>&aQNYsqp`(HjfU-#|O}7oeS+h|7>$ktf**4T+Zc+D z=$blkO^IKJjkf?o(ux#P^yUX01{b>}sI>i25zW|rl>WLu^8e@7GlT4it|LO7avL~o zuFg{_t8Y6O)(|}QV})BMK6*=!oTc4~Dq;11WdoXItX8p!q9~(Ye@9PukP?TU*7+xqrjR7LM*F zy!}Q;GW|dQ=l`640fM^kEP}2BS4vT>Z*z=EbYA9eI=WdF*F)qrygA%W4R4 zc?9!2zwsuV-}Z+urwZeH|I!W&Zc%f%GVa=qkFumKADXTSiW~s!}6nLzUK}{x56tl)tTA z?s=itq{EU_>-$PtaBdw4X*wVKdq;o|+xvNe-G9rmix-x}mxE?6CNY4fGqq*bkA!fqqksSSn&N)I{2wX~y`mqn1CI185x@8~ zBUF_N!{|qW z-${ci^hC=6#m_Nh=z$^=RB*!73XtdTVhZaII^`PjUDA75hdf^w<6Pir(eQ|;J}gaV zLUk)9RoEOhChOtmq_vNMnS_K}>I_iXJ8*qezDQbP3{~*$P^f@RdXZ4)Bf+UWk&xhZ zkjLJfb6)@(SRWGZLeh%~It*$t@YuIFE}A0J1}WkKB(kc!Sz?XV z;9kbimFG$~Q9PCP+<>P`LaB%Wu=ym{GC!(}B7Y&xc|ah9&c}>HR|8ayX-hpxyfPo3 z`;@@x+?(RQ@rwCu$Ou*$n6_>{Tk`gK&&gsydtxzS+}m5Bw_P5MKHB1wblb|_k1w8Wy6bin9-ugHbHqUoqIF46xW8Bmm( z^$tndU=a}%42un%@q*jPURpeJnFXOsXx+!zZR@8C@QfeN&3O(pj7&o-kX=ugUqSwl z9JQXua&W{WWrBN=GQlmFn>a=S9xq)Ty=7<8@|`_^jcXXQ&!+zVS7N53KQ zpuLbWmxW|Z?e)HAA9}_%qMpk%SLRc(?UFY*=lM>602R>Xn_fL0ofPH@ZBt6+d8{I6 zOQUx?f(3x@$SJ8_!hmrRlWKBq0hidDYjM1T*AhlpJ=!HQ8fDn>@~^J13>2}!vjujr z{m}QJYN3J^Nt7VFl!; z_O@qo)PBUb8|#aL1??Lc^bUY@K*_uv30{c2PpU;xP0%a!WRGbLh%1)Zx7(KD4&`F( z#yaVw>nkGFv;0G|rWXgF;@piW6tAedpFwjF6;Rgk8;dEw$G~_`#^qy=R$pv`!akcu zTz0C7MQCB>tdyL^ilaJ6=AvLry&#fMRC4PQFRKoj%=H-~{1Eo2$>8f5Fowi_ z$a0@HZxEu{;Q&Gn$Fs&DL`zCqiAVznfO`h*81*nBAST8ifiZ~<%|47dof2@;Xj8pClFUTk$ni4DCD3q zh65gwgc-O?E3`&VZYnIZ>8mKW|0DJjj+?7S(I%J|JC150Yu7K^OF1fciIH&Nj4oBC ztjPE98gF0%dN){fAoUT3H#RA5`P>@EprO+0ld00`p3{2IMPmE6P)Qaq^AGJ6993kA z5Uul*HW-5TsP`L&@4*WEL>SbJTH_gZwVadwYxV(s$}qgj-Snn{Z5Y>O%W!%8x+tJ) z<*Vd`e&~z_zR!PVm3NnCR^{z>CKE~TVr<>Ez=F%=ec_Hips>%Dr%}*g;?A1#N@hJy zMHKLA|Il8;;jRR~_#bNT!4YVSCb;G&jCps#Fe)0P_`7rW=D17WZ?BV_+;-aJ=nk8l`#rRNGVWRG zK7CjPs#@?QUM`u(JjR`R+WTe8hW)t*Dkppvsx>sB<}&Sr{5_TVoi#bj<8P^y(lpK{ zzq17M&F?2K-o(B54Gjs!cQbFpoz6ZhMxSEd#{S7Fs;_S`e+=0;6<{})@50NQnI}?3 z*yZQ?JinFWY$13M1uY{L%PUnoC4=Z}|NVqnF&ynV!crU~)3ov+q-Ee3a&Wh4HdZEExYCQ#ZCO2HF}5SjlDD z9sZhQW6|r-XrsTuoP*Nk>BhtMRgV7$2my2f9M>+GzePkr_9mD2tf({9o1Hn;?$~GC zO9TOzY1x}WgAYgLPYbxSzQu7(9VGJ(%J!EWZh2gF-0)e6Q+*NYPKt8w@bs zsjzV&3%`B zypEv*hVQo@3=%r$(iY~+-+vx2c>OYtR(g2g=DIyT;;kr_*np`t1LrHmnbKoZ+~ATM zlmTFHhWnsi9Y*wG7j`DgCxPN1ZMRw4%NbBw$3@i-w{vUA4-h8gnLbJDU0_R@A@mWB z$j3|NcXxN~rRi;nI}8;BZ4*6bO;E@7yIjnL@e%q)+Xg5sIC==PQESfLN{*4gQ^w{~ z6N4fa!NM_b1J>K7frr8@Rmr4niN!%K-EQ`aI=_l@a~H1)3U80vQ$rn*D0Qpj{3Q2$ z7vsckvyqAvz-f&)pn5wpB!pbfipC<+?y)^%yx{e#IX2egH`+Y}CU!KTHPYK&0_iNb zw&gv&$?AL`=QUDlq4$Qm3xB^?#^Y0Mp$`m^XNN;)nmd_?2pzC>rYF0R==ooc;mORZrx_g z_=(wYF0-Xjq(f7p?=G3r%pxC<2be`<1-&6VrpU0=q_$iXshvZ)Q;=5$3-t+L*REMjih1ws-&GobUV?XHwxpm^2CAJ zBX7&dj{kalvYGB1aLy8w+JF<^)dJuGyKaL99w{x%8D-7OD5QBK#dEjU^I|Pu6(4Sb z#`qW_J8QrorrGq_UE0`E3A9=nHf z)nCr<)(ECxKektl7rf4rjK+z);^mu)Yvh$o$;8m*lP;mVN|XUSw%%|= zRDon&83S;L5T&Wb80S9FS+N{>`+Ao5unf>u=!Q!3OuEMf2yYS>GO!t!5{*)QR)f?H zhi!=*d1FrT&V4IIYEnj#DgKj4e^J4)vCXb?*SN8)x!`Wa;yay=4H$D4_(&e5_}ZP- z*dF0x4T!1{PqPnpW8g@mn6uUMDq*e}WAnN7%D6BOk6um(g_G4|Oq6kVGY7A4cx;xI zn+ax5esK@I6PJ5AEkL6kzMg@68+{uq*%&hC;pn}hjF04-+nli}OwNR^)+yKFu|NV> zQz+?t)x0XdZ#QY3|A6y|8K`>GxEG6amYs5Y!)>=qMxSy=+tJ7Q*9z+Ep(JjlvpQ~w znBfcby`bTOUnycE1~U(suZnZm__3KNz5TR2u~_{*T_b`+HEj1Vv0{A0Z{+K1cQ9j1 z?xQ0N6X;7_`Xy5aal_V1S|Pr4#oUPZ*Gf3FtQhFqAxKF4EyJVG#h|89(K+q}c4xty z?Tov7HN$s5mvl*ian(_pQ)fx`kFDQH>^@U}-C`r=Z@8}9oy(x;U1P0uYcaN76Na+n zdN2wD%ce*+;Er+8INK#eN78ACT?{P5h$7D0F|NoDIw!DaCUME$CG!|ORgL|Xah8`SGF>oWKn#6nU*2BgZmo(lib^ub zYF}*(d|OEc>{OQo^5~N25;(RyTnxoWIKM^LD(So!Dd~DkqPvN)_2cQT4v#XpBP=+LQ?n}c0rveyojKwdez$KIx#k- zTr5Ukw|9x@06M7Kt~v#}zHKZ=*1p#Mv3-b(F)Xm}PfuN2vaY)@x_poA!(6PJ37qy- zu6In6^sJbJz$HuKY}-ea)Q^Q&vmzN5&)b){wX0_KS+jnR?W0^w)v29GTIY@ucRh<* zG(Hs4ZI`T)R&3vzbD7Uubm;wJ1rc>O>F>Ak=t`R(iK)~WMrcAXnkas#7+s#jOY<>$ z5isGxpVSzHbpVO?nGay&@^TYJTu5E_Acw!-sjCn1G3Ql``4A8M5lC?Q9Ylwjj4y=6 z?*$c|ZhA^_<+L`XkL_bzXcqi#!OsnS3Jsi8*n8?NqYR`mD`b0Guyv@vF-YvggBMSA zI_G;8!8vRZkuRztvhSlYr86HSy>ZgR{dKmd)wNu_Gp(<-<;Nc|8xVAwYUR7FQgW># z5TFY$xL%v=$M$h9y7nkGixx~3AI2NbHN0mWEK=_7>T{83)&^V!!!4*PbNxvG*H?OW z5O{it&O6-9lvwqj0cBA08j}@nm=F*sMrYbT_lr7zf^)AXp52Yq0|6Q6Ann`=?wtn# z27w=mB0(~ZR!rXd#{``(07)bGF%5O- zO#7#PQRh!`mP0Bu3S?6WU~C|ax1hTNz&!*BQxE~2nJ`9#J5Jx9C(7d)rX0b*jZ5c0 zwxEdNYDg`-l1cE~0w?@2)dJzo4j3dqA%+!1aRz)6LfG7CnQIhOQL7qL5SsRn{i4pF z;ym8{!@KV@$7WG7SYRv#j7I;FEQB(VD4TW0FEJbLUs97^Ux?cf} zB`>xiH;WVJM9~H=XYcyt@p+7#c1Yd<8l=~ET3&>@Ilord{X^zM&{z$%x&Jrnr2qqyg-}I9mdE| zqJ1PXw$F00mS~uo3DzK^&WP9nDAVBVex`CT`vTO&H*}(d4~qRnJ}P$%bCowoT6@m1 z22Lru2-ccdN`_}!%DGV*Ee$FleJ?!RXNC_>-kSR&cutXnQV`Ogww9Z^{v7A=E(){s zwm{v&IG2qArngqiDB9&eqQZZ|#stN~k4OtT#8pxX^A-=iPyv?!bGE`k5^xZ+W$;TB zviKsyyd1H6>7)a?EMZH3+K>80oyDUJ*8cLi4(|NAo7aoL4MehC$4BwmIWpcQTj!!EiKI=Zgi9CA$E8T!dcEaNQoDLzZ{W1QPveKkOHE{ygXDZJqcO z`yh<SQekYlGqzG ziG=o)`YKX8d-~JnK>sqm-bBQ1;sOD0unQ$N?6&He>`MS-F+F#@z?{AkH^@J<6qM(@ zGrla}jf0_d--9-wj#|`}>{5zPmJGUadt8EB8DSFiX+Q24bruX6Gf_Om<@MDCG=34e zYFg7}6##*abrBv34a9kuKki`QMP?yqPUy=*!w?E6g!xu@BsqY=KtKCRwaZ5JA9$bh(`p4l|}HOaQMZEKZMm+?vRXIlXz}Dh|6UJ=$hq z3kDr1(8cb$PO$`VtGk|J*cfQ*ttC}61_kI$`&qxJ^H({Kk2+rKHG*cl$M=dVJU+=;fx9O@ak*1$zRFh^oM|Lj(BNo<^zYGY*#??U3#ywCLO>h_r;^LXM=pXt;odss7 zv=w9boqGL_$LV{2P5rPF2%fHi6(^@R0zb}#^T<@ygtKRu3P)g}Sf0TG+l+ILshqR6 zLw6xQlq)ZMl(`KlG$Sk>mz^O?ac*PgM_OM$8Fx$OFcpxTx%NApbRl}kvNxS*&VmI+ zKJ5_7V{f~+afn?glU)s`*rM+g$Jy)pl$j**q;vL1+kvBn}Ef8xJEaNO2Al z*cE*No-U`j*jC2Pbt4=aJCFc`P{4$%;Dh(JFj1}gsSb$Ru=)HAI@bD$!LF=srrsc; za2|r2?G?3DdM66fI^)4v|L?Ct!9%m z#DS-RA+PO&(sJha;yibNrQBg!9;6qqdx6#{(8<1|Lic$l(7*l)ny+nt&SCo8Diz`B zEo|+?9;El;8xyysfwf+#vJ{!nVkDi6Wd#TD&L@pD)ez;6j>b(TIzK{+ZOq<+B5?-C zyomw~&Cy#A*}!FO=GNG>?qUtidIeaoQzsNcttQGwUQ< zqTlDDCgKutTUHqwHQD!(G^Bmr{8}f^vtep7JvHdvM~VQxhvSed*-LPpz&SVYTkvYD zJm+x~XAsI(4Li7UFQi29N-q+KZ2f*_9;}T+^{ri)r2z{qX`t9uV=Hi>S=(&zHyIh< z`OBRhF1cUU2;^nc>ci=&$hpCPDKAWF#l__G-;^*ARY4E)P}ps|A!LTrY3{h|RyGp6>z@%GZjV9=m?L2lN`9AgHjPNDg;d=UiK9g!UnKj4T<54L*;N2=A zIX84@ncrpMjF!=aKM!$K8EBloN7onwk5>uVnhJoR8*;}$4CL2umJ}I4c_TunTX;qX zh`##-X!TbbyM#=%0*Y+r>2k+dKTgJ^H0@r$bBHGBV@{7~k@Vkj){rqHS}9vb9+`2! z^A1GRx19$~KjCtRs7Qj#U${EGok)M$Tll-N z2Q!=zxoEch7r05cA3FOoyhd%D$91#wJeP%7M^)0H_2J9-MnK%#bhM2p9sCo>M8a`pt@cl zdZYt@w^BYt8e_d6J1rm4iqtW>U4Ih!^*V7S1=r2c^NiN_>07t!xa=m^B{V-neW6bH zIA=qv`SVZA$`31e?)KNb=x4|NxFwfZoGljdvvg#xN{)90OD1)B%#`7e=`gmy0^@j} ztoOI3Jd{g>mH@e6`sbOx@%o5C3C16Sa zm@&rT?j|r`HiSqsVA`{1w0V9*G zY-3(|&#Fjw{X2zpMo~duS4|js`r3#cn+Et)hZDH;^Qph*(k)>Xu-?+;13w^{Yo_Oa z<1(k<^w#UL9Sg%}ZPrEH#s@|q`8RaA`NAmDi#Vs8yaDUxpQ9%=`Vugl-IMspG+MJG>`xH|Nh@F zz6E3N)(kLv;f@j?p!dQ?>ds zSp>uoSsR;)QHZY%uCe(r*iA$PBhaTEC&6Dp@cAnb(&{c115>6ohr;5dH^g^Y7mg4dhnjdKkr$3{`3A8{i(l~SV1v*a;P5)9g zmSU}+y=%tR?zneWbVkmaqQ>TP=5bYo_h;!ky;tNdquDzC`pz?%VO7cpadH3pi#>pG zzhH1C5{c|@$)2hPG|!U=WyiE?oXmNK&)Tf%-!kgnB(8_wC%M*-Kn=BbKpQFj0F&nI z&&|@Zu403r*KguuyGl-3XyBd-Bo}9G*7BE(_8O~oALH7k6yEOp&wg`|ZXj~+Q$h%s#a_*#3^8>8Z|#=rYDY6$$z2RUlo$8L57l z)Fi{xYJ>)^CurYqO8Btr*-SdVXAq{bxm*|ow`7iQka~wM{fksO{OQ`Wn(|?XQ3@?l z%Hh)n!>4nuak-fV665u{8x6y4Y+2A27pSDG%=;NXJsx%Uf2N@;VrhtF-n$4J>X_2f z_q}$~>AYfGxl5VV^Bn?BPIe&X54o;KGW|XYy$C^mKfJ_)poebG@IeW1n*3&IKgoTT z*B5o$+1$)-{Z&y%E4aM-q*d-sa4Z_2l8IH+AuN8$+=$4 zJZlOcn{ODbYX?wemkTR!$z91(w2*1hs&qiIV+GD9ibI~Xf|r~8Q)xJ$()>QouVo0M zTgpH_@%1*kEbH_}D+&i@GT{Bo=_l#)e*&1p*hi(n4(Ov8I_K^KAkS(;p`~}BIBQ#a z>0($#HCS==2sEXd;$3O+7m~9DWC9XUDXKxql}T!?@u{FXZIsrnoz?6)KkPj&QgD3u zq>Hz1^;7__TJ9>6(7~}Ai!L8v!1d!6U1rLLKFm04F6CqU4HxUp8m7OAYfVC*2*P;4 zO{GA<(96{wX+;e2Pg-06Knt+*Mu-7spEX5~ExQczp*KQrV6eVW;ay4vtnpP<^b)c_ky?dbT&Yrh zZvq7;t@d|qGdht2$HKcTyI<*xyCNM2m2p|)c?}pS;f=Qd(vcfTdh=msx^BW^Du>FN zn+~1Z-E_ba{4N1&kf9Mktcng!HCul`tXvDcQWA4%l8EoazGbVo?FboABi3~ z-^Tp|{yx2~SAh{l8kr)Rwb1&xJ(Z5G6xJ?Syp*nr+-N~>Wz)+YSv;2!A|6qB zBuasD1v$IfEUH=LU2_N5s-aBm5)UIldiQAEuZiVU`@AE+|x2Wn3U5_N1e;ySX~fO|ga= zklj*Y&Rlgb{%Xt0X^AUBnRyvmppFBe1Lgc9_>-oiysZdx11`Elgy{ggU^a-5k-1g5 z*lJ<1wOjzoO^Rpv7c_32gt}S2Q(n9f?JPO!a z6?Nx&e~REPd4nmkcsobMTbmEEua+2h_uFV22|RC^WcHjQ)3;AT)g^x5*PdPc=Tz6X z5!_|O>SA@z|6ri&8dXf$Luk2Y(6V9vv2#zGo`Z_tRZKwj9{^I)Xm= zUofP|h7T2CAkNL&rGZp_>$a56Wu=k`K6^lL9vOE``{)E`SwBQwD$KID4GEhh2YBo+UE^Kbr5 z@JC)D{jnM$_*+hZ1*Z04X*BaRmgg1~QLTlPil1bjK&BfD=r$(Zne^@1Mun2O@iez~ zOSqwT32_xzg?dFH9ja|;fowTvDA9EU+S7?^SmTiibF<7bAVGq)rR z;VHuw@&zWf5Z6B?IF>lXvYili3plsHT>8q=aUZzUCNhN{&PKm!n|&09)J$iO&4is> z%IPHGD@-y&;M5YbbHSE``F>4#+035ncoCarRT~OteT`!jLe6EcN+e~GK-f+-aTh%| zv!=M+DmfMRUv~um0(^|YR*S4%#BY?^FDtGUbDP$8O)62}V5)o@H$-`3VEJmLb}EZ& z;oN%1Qd+kAy>%HZ^^>TG2P$6pWW>jU=rD8h+U@MzvNbt}$0?6;3{o@_hxDhL%U&mr z?e=(4uMM0L{sQ1zbi21p%3l56tYi&OT}4_}${z zRca>|-J{MeVT>|S5Y!z1K8H0ReZ<2|rCkR@^$Qv?Hua18?6Bz%|z`pBTU<9owtM3ts;t$7&;)<**KExZGISH@BHj zjKMG@M}t$kCs-?}b+rAavZUV*~LsBk#x&!%DS zcdXmY%V<&yq^rf4G?vjdI(CwB-c}?y3Dl@C?Ahd{m_l^V5i`5LQw2naT{)DlW$|HE zO#e;3>){jdnX}gcB!lFhryz3Q>%2FWTQ&`+MCg_b&cKtJNxQ# zkvB>sS-+my{hWa{L{_)U6JE$X9X+c&lFz*S#Ka2Okl6AXV{pjdk)6}V7Iqsdh{#o{&AhU+ z80y5Jg6s}x=biG{f=($2iRLD*42b~{5ON4-BbIc{lT@!IMiX=h%&&FdOF zU>9~BjDyEVcHWhbO?E!#Nn{P>$Ru}JNdFLtBkd-yUSfub53eiqGLgsjV=k;Ub27S! zuX+tNYNXxdRZH_&zrqW>A_F`}9{qae<-XnT=g)e%fm-$2S*t93V+*gwe!wfdC?=O- zzsai>H}z{d?lmp4;WhO4xM%D8*mAeixPV)a-R8v_D}%m0?s=0}myH3J+sw5(MX#Op zX_FVWc&|PFM<4G%+-rmvJh{BkdRcHX0eMxmh{`)_ z%FNE&*Bvr%2iGVYB#qj+_>V1j!)?)!G2yj=z(~8vt21dp+Pi6^Z1&7$ymH^a5dq%o zuSIc)n30zcfW{VH8<`Ydok>F^kF=Y-I+})zc|AmKoQ;@~zF*ILzUTa|6hj4lgZ-`R zP`#UvXZMz43$OOofJu0@jKQ}f?Iy3v$e#BmUT9nVx08*Vd^TvpYvSK>JkNZ-tLzOM z!l!NC!O1QC*urarCcHLejI^7)COaO2V8sdBNBVxf$!7zn@GAae#cn>HpEh3b`a2w3 zScMlDrJ4=#F_Lfc>bfxC`!Gb|gKi^zzux3Se9yW676`1$>EFR>lULV~Az#Dm3aos# zIJR$dv92&fB@eGFu-fF+SPgae5oF9O$f(06pAD?us;-UI&N8vdt7!(T!mH}bs7t@z z;u9O7`7)FI+B#69CCu|lX#$Ge@dm(WUJO5taX)m%)z|3tK~Xpi$h0)iJ{B0;UvaT| z23nNQ&7ae*kI9gZ=?NFoU=T)=A04`e^$a!o=YKPjN@miKhiBw*8 zAV&oKE^SU}#W+W5?{bhna_`r()Ne81dzO(5%{ROzgd!G8R^4{04|UerLmGDC|e zczL01%7ec&Zk{6t-G9kzQy|yyk1h1KKQ1t)W0QAB9uUdj;0#Z2d8yafYQ(s*y?wl< zKlhF`u2W5x*2i08>xf^Ed7rNdgy_Z`E-$oA-3XSZ`Ew}bmus-|v4uql$l>TG<4;A% zRkA)MUIF14%)rqnF@9D9btLj*R$M84)c)DU9YJN29H3$Ddz?F<#^r^!X$_p(JFZPD z4|qL~Yd!28t^3c+L$w!hU2mG-V%T?0(SXj9?|x?08~&oAbtu~(W`djCed_~;;ldf@ z=q%fe&u4OZ`iyJdK13K|92iC9y2J}+KM3IEg|-Dlf*<-zAwa{-!{I9LZB^dF$Fv>G zjkhW)d2<#H5bH-36bwK1gxQ15CSc*xA94UC3&o`dgI1JdE>kbGn^VtUa=q>gq1`jw zrv^s2E;0rZ3mC3y>SIjI{uZ3FU|6`~B4YjjFYioyY%QuN%;kdrM*jsSBt{db_;-K+ zHzq<<5X0qwkP5NdWkFwY8qPvyXq^4?nnC>rh^u3AXm;SW5$sL zL-ELQ8f_h9(o$lAD{XTl)CvMUWeQ3sFQgAf0IV;zZGDNL5SIT~rtTI)$CXS`D zUZtk0W1BfZ(oHcVFsj6iY=A(?!WV@sG&DZ5uH3_fVOJAIKf9!SS_D!r>D!~~DO0ta z)@#BZ0Rm2u$xQ)ZreKr$Ou;7pJynQ8WTl9DmTa#BK2^ZV5GV2~=A-M8W9n5Q3WMw= z3V-o?stB%xt#oc36CkQb`jI7*jJ>Tt7~+@V$|O*31V-8gXieEDxZELrXm<)_W-l2) zw5nstX^I|UhKkdY<1j;1iKZ-{ZwH#Bau2U3A`Qbxr720-Zy={VF$7b#ZqQ_Uz%X_q zsDes6M7KkWcZ{@~F3v}i?ZxB*`Rudk!!)J?Gg;)AOG#FAAo7xqP=`9EIAc-Abc8N2 zjExDbe(0dx>SGc;V%{4!r=cVCGjNhp#_i9~_UM_s4b17a~OZ51mZrrtrD$3jc; zmS9Z*KvFc*{)BG$KbvVP^3OCI3W z{ThE$9-?>SLEnLr9gfYKuat)*^*v$XaIGalv0xtJBg&-miPC)^54Le)2suy7g}&)< zp?S!{wMq@na;ijh3pstIj;lR7S#00V6`H2Dh17&m2;@rNEoXUrX@&mjn4rY1Mn8`o% zGe*{xJ%16vW#l5c7EiZB5fyQ6s&xw`VU`=ErU|Vi zy+~vT3TUHKx5nc$9$3MpAEg3sgUw)6&CR5AlPif(S}j!(rYi8m**WzBlvdeIQ_9__ zRob|qw8b1yktNLT9w$JG@phx!26+<&VOOf^9)eY_=#Zlvy7P!nSq=L6(KFLCgR4;1 zhGeK_RC2x$np#YzxdBl$kHv*+*Q17moHmyeU9fRPYvjVXU2DZYinKe*2BVkV2*pgL zCRRKlgzhQ(DVE9rx*Z|(xItGmy7yr+7{kXS$8vWDud5xZ6^6_Z;pKw4Ja za?H5czPkg~UOuu4z?=D?Z0(TDV!_9rhecz7=k>p0cMJ8S;AK`_H(_Z8|>!Foh5Sb3`EHHyr;X0<(l=gp=bs7JWrh0;mKOl(oub!EAWT)#fp`YJEKP{igyo$@aN)e!u)=NP#BzM>QAXMw=m@cpKI)T2WRZV&mTE8~8 z>DWrh{C*89wAEKqra_Z27-1#%eGQwB{yCTJT#QrQc>G_@MGR)KeMKC?oyTE=kw2BE z9F|}Hug#-1aP=H~=6^||C*kceI=MgGopg>{8PnfKIO#n7LAmE5&m~_fw6DkJ)~D)) z>$%FVx(qt;T=5@rPR97{Bm7bNrmmlr_xd4jX0dFXbCnhzbz@mI+>ae`5r@ z*|d+F;*<~S+BSXt&UtuR*l&t88Dp%>!8vpE^N96Z8n-dicrw(2V#=g;R6>nR%Czr~AjB5TX3!O(ezqkB5WYWtI0>ATf$!PO|J zWYUeVQIA_xAHCathU)Dx#ftxMwVaN|0>g7GbR4mM&)~fO(|zb8)a&L2>N!2MX)>M8 zx{uHg!zFZ^s|s$beyi_eN31_+4D)*aMzgUdW;qrs=5L|+AB^%C@SR z%viMrm9BkEK95*W)1b6sleKj7!9{&=be>{O=08v0?N)6Oj=D|I56d;-pHn#g6WSf<5nm*d7>;PdkfxpdP?Ipdt};k9L<51(R9 z0lSHtPP7i7NA-FDG8z#i~_S6q397PK91{Pn~pfNoVa^`(dlox6{?~ zrDtfd)rX$%h59_9%S%mcyP!+g3*&Kyih;4Lsgi0BV>7f%LEEexoiy)}Dp|_H3(|CH zG#-xQ5LXOom)c%te~trhRW6&*KF#WGbmuV#d4(^2IJv{1ak~e9ND^w2W*LsZM$dQoJR9X>XJ%O=|63hT$h zA~N=2eSCuD{e8*M0`3Qb1G-N!j{d}0L0K0dQK`XwU)9IJ-93TR6<&v{RQO%0Wp>t) zeFEMyLG%Sz^xZkzcM6f9He%U)1h{vsp!^;UWz{IZXnF7fwXpdJDAP{H`=76j_3zct zjSqHv!ema^mA*9-Momm3w-5>v0oRZ92@ElQQH z-tjzQe0r>)tm}>r%IFg5OKRB>ss*b&Vubn3SV8%H8jX1Pp}%EY417V=8wM;a1TE6q zXD6Vts65+miS5)^SE=vnHR9(ch`u3~p*!70f9Y;e=3I#R`3b1@#R??9npcW{Qi#+s zhxq_;GV*K4;&<;D0lqO-P}UBv7_dCJL#>K7BvK=xTL53Imr7~l zaSIj2fQ5wtqF%ieZfe1XZUMhq)Y^}4^+J7?UBrOjVBNWa6V4_O1gf~53_kewq*8k) zMI{ni9vG-xl?;BgWrWe%GamNLO;QR2g{u`-Gvcdmf!T$;S|!Ir`<>#?Bp_XRrguHe zL5*7o!3DG58$l^2JTn>|3io==*l>3~GQwz+Fdj}P8`D^-9qu)BEnL6Hyff#B@!(iN zS(}ZDB#qW9rp$t4=?Yj$5yvtt3N2{(;RIIug9?1ZZj1x0ZjA_*c?`Rb2W{lWL+g3H zcido+>m?fWRxLgavR_(X^YD`qma2p-0XSGl!vgtd6J#x#hmq?a$^iPL+Q5PZ2=Q;@ti}HM1YEm;0xtmh2K)m0 zXthBPZXxiRcp>~RC-_>O$`SO1481hJVOzq8ZNzoM)^#Qz2fvvNGy; zJVM0|=E0M|ygXu1RysHf0~@R36%Pmrg5YkG115v~FJ;Dhh392kBviu+_X~`V8?c27 z2}rjp$3r1=Ie>75BpbRA@E$Nv@Lzm`rrTrV@hlbEA~xScSh>VW{!y{ebhl$XUZmn` zAhns3+u79+Si5aKO;*`1s6Gp)6Q(w4ujEjeTvEqd-~6^K-hSmNU-^bB IUU$iV0A Date: Mon, 2 Mar 2026 20:43:09 -0500 Subject: [PATCH 17/23] fix incorrect bond opacity lookup for bonds constrained with fix shake --- src/GRAPHICS/dump_image.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GRAPHICS/dump_image.cpp b/src/GRAPHICS/dump_image.cpp index 57115fd4648..0e4bbf1b11d 100644 --- a/src/GRAPHICS/dump_image.cpp +++ b/src/GRAPHICS/dump_image.cpp @@ -1502,15 +1502,15 @@ void DumpImage::create_image() xmid[2] = x[atom1][2] + 0.5*delz; if (bcolor == ATOM) image->draw_cylinder(x[atom1],xmid,color1,diameter,3,aopacity[type[atom1]]); - else image->draw_cylinder(x[atom1],xmid,color,diameter,3,bopacity[btype]); + else image->draw_cylinder(x[atom1],xmid,color,diameter,3,bopacity[itype]); xmid[0] = x[atom2][0] - 0.5*delx; xmid[1] = x[atom2][1] - 0.5*dely; xmid[2] = x[atom2][2] - 0.5*delz; if (bcolor == ATOM) image->draw_cylinder(xmid,x[atom2],color2,diameter,3,aopacity[type[atom1]]); - else image->draw_cylinder(xmid,x[atom2],color,diameter,3,bopacity[btype]); + else image->draw_cylinder(xmid,x[atom2],color,diameter,3,bopacity[itype]); - } else image->draw_cylinder(x[atom1],x[atom2],color,diameter,3,bopacity[btype]); + } else image->draw_cylinder(x[atom1],x[atom2],color,diameter,3,bopacity[itype]); } } } From a97698af6845ad191d2a43800305ecde08f1c191 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 2 Mar 2026 20:50:49 -0500 Subject: [PATCH 18/23] cleaner version of bond opacity bugfix --- src/GRAPHICS/dump_image.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/GRAPHICS/dump_image.cpp b/src/GRAPHICS/dump_image.cpp index 0e4bbf1b11d..e1c0b560399 100644 --- a/src/GRAPHICS/dump_image.cpp +++ b/src/GRAPHICS/dump_image.cpp @@ -1448,6 +1448,7 @@ void DumpImage::create_image() if (atom2 < 0 || !chooseghost[atom2]) continue; if (newton_bond == 0 && tag[atom1] > tag[atom2]) continue; if (btype == 0) continue; + if (btype < 0) btype = -btype; if (bcolor == ATOM) { if (acolor == TYPE) { @@ -1464,9 +1465,7 @@ void DumpImage::create_image() color2 = image->color2rgb("white"); } } else if (bcolor == TYPE) { - itype = btype; - if (itype < 0) itype = -itype; - color = bcolortype[itype]; + color = bcolortype[btype]; } if (bdiam == NUMERIC) { @@ -1482,9 +1481,7 @@ void DumpImage::create_image() diameter = MIN(bufcopy[atom1][1],bufcopy[atom2][1]); } } else if (bdiam == TYPE) { - itype = btype; - if (itype < 0) itype = -itype; - diameter = bdiamtype[itype]; + diameter = bdiamtype[btype]; } // draw cylinder in 2 pieces if bcolor = ATOM @@ -1502,15 +1499,15 @@ void DumpImage::create_image() xmid[2] = x[atom1][2] + 0.5*delz; if (bcolor == ATOM) image->draw_cylinder(x[atom1],xmid,color1,diameter,3,aopacity[type[atom1]]); - else image->draw_cylinder(x[atom1],xmid,color,diameter,3,bopacity[itype]); + else image->draw_cylinder(x[atom1],xmid,color,diameter,3,bopacity[btype]); xmid[0] = x[atom2][0] - 0.5*delx; xmid[1] = x[atom2][1] - 0.5*dely; xmid[2] = x[atom2][2] - 0.5*delz; if (bcolor == ATOM) image->draw_cylinder(xmid,x[atom2],color2,diameter,3,aopacity[type[atom1]]); - else image->draw_cylinder(xmid,x[atom2],color,diameter,3,bopacity[itype]); + else image->draw_cylinder(xmid,x[atom2],color,diameter,3,bopacity[btype]); - } else image->draw_cylinder(x[atom1],x[atom2],color,diameter,3,bopacity[itype]); + } else image->draw_cylinder(x[atom1],x[atom2],color,diameter,3,bopacity[btype]); } } } From b602118fc80d1d66f262baa2c2eb37a7f7b2f092 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 3 Mar 2026 16:24:33 -0500 Subject: [PATCH 19/23] add a preset for compiling a library for use with LAMMPS-GUI --- cmake/presets/lammps-gui.cmake | 70 ++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 cmake/presets/lammps-gui.cmake diff --git a/cmake/presets/lammps-gui.cmake b/cmake/presets/lammps-gui.cmake new file mode 100644 index 00000000000..5a1792100ff --- /dev/null +++ b/cmake/presets/lammps-gui.cmake @@ -0,0 +1,70 @@ +set(WIN_PACKAGES + AMOEBA + ASPHERE + BODY + BPM + BROWNIAN + CG-DNA + CG-SPICA + CLASS2 + COLLOID + CORESHELL + DIELECTRIC + DIFFRACTION + DIPOLE + DPD-BASIC + DPD-MESO + DPD-REACT + DPD-SMOOTH + DRUDE + EFF + EXTRA-COMMAND + EXTRA-COMPUTE + EXTRA-DUMP + EXTRA-FIX + EXTRA-MOLECULE + EXTRA-PAIR + FEP + GRAPHICS + GRANULAR + INTERLAYER + KSPACE + LEPTON + MACHDYN + MANYBODY + MC + MEAM + MISC + ML-IAP + ML-POD + ML-SNAP + ML-UF3 + MOFFF + MOLECULE + OPENMP + OPT + ORIENT + PERI + PHONON + QEQ + QTB + REACTION + REAXFF + RHEO + RIGID + SHOCK + SPH + SPIN + SRD + TALLY + UEF + YAFF) + +foreach(PKG ${WIN_PACKAGES}) + set(PKG_${PKG} ON CACHE BOOL "" FORCE) +endforeach() + +set(FFT KISS CACHE STRING "" FORCE) +set(BUILD_MPI OFF CACHE BOOL "" FORCE) +set(BUILD_TOOLS OFF CACHE BOOL "" FORCE) +set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/lammps-installer") From 8b45ceeb97c9b1df95584acc22fe0bbc696a98a4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 4 Mar 2026 17:43:40 -0500 Subject: [PATCH 20/23] this is no longer needed --- src/.gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/src/.gitignore b/src/.gitignore index b6da4da02e2..ef50bf2b835 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -845,7 +845,6 @@ /ewald.h /ewald_cg.cpp /ewald_cg.h -/ewald_const.h /ewald_dipole.cpp /ewald_dipole.h /ewald_dipole_spin.cpp From 1279e336fef73ea953543637f9387592c52f56d1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 4 Mar 2026 17:45:04 -0500 Subject: [PATCH 21/23] some more updates for the LAMMPS-GUI custom LAMMPS library build --- cmake/presets/lammps-gui.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/presets/lammps-gui.cmake b/cmake/presets/lammps-gui.cmake index 5a1792100ff..af18bdac9d0 100644 --- a/cmake/presets/lammps-gui.cmake +++ b/cmake/presets/lammps-gui.cmake @@ -8,6 +8,7 @@ set(WIN_PACKAGES CG-SPICA CLASS2 COLLOID + COLVARS CORESHELL DIELECTRIC DIFFRACTION @@ -64,6 +65,9 @@ foreach(PKG ${WIN_PACKAGES}) set(PKG_${PKG} ON CACHE BOOL "" FORCE) endforeach() +set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) +set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE) +set(USE_INTERNAL_LINALG ON CACHE BOOL "" FORCE) set(FFT KISS CACHE STRING "" FORCE) set(BUILD_MPI OFF CACHE BOOL "" FORCE) set(BUILD_TOOLS OFF CACHE BOOL "" FORCE) From f562372072f501225ee7952a243904bcbf0b6cd5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 4 Mar 2026 17:45:38 -0500 Subject: [PATCH 22/23] use new feature, so we can color bodies by atom properties also from LAMMPS-GUI --- examples/GRAPHICS/in.cubes-and-pyramids | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/GRAPHICS/in.cubes-and-pyramids b/examples/GRAPHICS/in.cubes-and-pyramids index bed142c5151..01e55496758 100644 --- a/examples/GRAPHICS/in.cubes-and-pyramids +++ b/examples/GRAPHICS/in.cubes-and-pyramids @@ -47,7 +47,7 @@ fix pbar all graphics/objects ${out} progbar 3 4 y 24.0 12.0 -1.4 30.0 0.5 v_pro dump 2 all image ${out} cubes-and-pyramids.*.ppm type type size 600 600 shiny 0.4 & box yes 0.025 axes no 0.5 0.1 zoom 1.5 view 80 0 fsaa yes ssao yes 315123 0.4 & - body type 0.2 3 fix pbar type 0 0 + body atom 0.2 3 fix pbar type 0 0 # set cylinder diameter--^ ^-- set viz style (1 only faces, 2 cylinders, 3 both) dump_modify 2 pad 6 backcolor darkgray backcolor2 gray boxcolor white & acolor 1 steelblue acolor 2 orange acolor 3 slategray acolor 4 red From 320f26bc96acc3bfc224425cb8c4c244920131c5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 5 Mar 2026 08:42:05 -0500 Subject: [PATCH 23/23] flush small values for stress or global scalars or vectors to zero to avoid false positives --- unittest/force-styles/test_fix_timestep.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index eb1f1c80362..83d2acace79 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -197,6 +197,9 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) // run_stress, if enabled if (ifix->thermo_virial) { auto *stress = ifix->virial; + // avoid false positives on tiny stresses. force to zero instead. + for (int i = 0; i < 6; ++i) + if (fabs(stress[i]) < 1.0e-13) stress[i] = 0.0; block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0], stress[1], stress[2], stress[3], stress[4], stress[5]); writer.emit_block("run_stress", block); @@ -205,6 +208,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) // global scalar if (ifix->scalar_flag) { double value = ifix->compute_scalar(); + // avoid false positives on tiny values. force to zero instead. + if (fabs(value) < 1.0e-13) value = 0.0; writer.emit("global_scalar", value); } @@ -212,8 +217,13 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) if (ifix->vector_flag) { int num = ifix->size_vector; block = std::to_string(num); - for (int i = 0; i < num; ++i) - block += fmt::format(" {}", ifix->compute_vector(i)); + double value; + for (int i = 0; i < num; ++i) { + // avoid false positives on tiny values. force to zero instead. + value = ifix->compute_vector(i); + if (fabs(value) < 1.0e-13) value = 0.0; + block += fmt::format(" {:23.16e}", value); + } writer.emit_block("global_vector", block); } }