diff --git a/cmake/presets/lammps-gui.cmake b/cmake/presets/lammps-gui.cmake new file mode 100644 index 00000000000..af18bdac9d0 --- /dev/null +++ b/cmake/presets/lammps-gui.cmake @@ -0,0 +1,74 @@ +set(WIN_PACKAGES + AMOEBA + ASPHERE + BODY + BPM + BROWNIAN + CG-DNA + CG-SPICA + CLASS2 + COLLOID + COLVARS + 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(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) +set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/lammps-installer") 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. 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`` diff --git a/doc/src/dump_image.rst b/doc/src/dump_image.rst index 689cd33c36a..27d8279a2db 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 @@ -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 """"""""""" @@ -585,25 +587,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 +625,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. ---------- @@ -1125,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/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 00000000000..aa91f6a2c6d Binary files /dev/null and b/examples/GRAPHICS/hbond-diagram.tga differ 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..01e55496758 100644 --- a/examples/GRAPHICS/in.cubes-and-pyramids +++ b/examples/GRAPHICS/in.cubes-and-pyramids @@ -45,9 +45,9 @@ 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 + 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 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 fbaf19c752d..34d0f831079 100644 --- a/examples/GRAPHICS/in.peptide-hbonds +++ b/examples/GRAPHICS/in.peptide-hbonds @@ -30,7 +30,8 @@ fix 2 all shake 0.0001 10 1000 b 4 6 8 10 12 14 18 a 31 group peptide type <= 12 -# compute center of mass of peptide and center of box and displace atoms so they will match +# recenter system so the peptide is in the center of the box for that we compute the center +# of mass of the peptide and the center of the box and displace atoms so tjat they will match variable comx equal xcm(peptide,x) variable comy equal xcm(peptide,y) variable comz equal xcm(peptide,z) @@ -57,23 +58,20 @@ compute hb1 all hbond/local 3.5 30.0 pdonor woxygen hydrogen compute hb2 all hbond/local 3.7 30.0 woxygen pacceptor hydrogen # create donor/acceptor hydrogen bonds info text -fix label all graphics/labels ${vizsteps} text " Hydrogen bonds donated: $(c_hb1:%02.0f)" 207 72 0.0 & +fix label all graphics/labels ${vizsteps} text " Hydrogen bonds donated: $(c_hb1:%02.0f)" 206 62 0.0 & size 24 backcolor darkgray & - text "Hydrogen bonds accepted: $(c_hb2:%02.0f)" 210 30 0.0 & - size 24 backcolor darkgray + text "Hydrogen bonds accepted: $(c_hb2:%02.0f)" 209 20 0.0 & + size 24 backcolor darkgray & + image hbond-diagram.tga 190 210 0 scale 0.25 transcolor auto # create colored arrows to go with text labels -fix obj all graphics/objects ${vizsteps} arrow 5 80.0 57.1 27.5 80.0 65.0 27.5 0.35 0.2 & - arrow 6 80.0 57.1 25.7 80.0 65.0 25.7 0.35 0.2 -# add progress bar -variable prog equal step/${runsteps} -fix graphics all graphics/objects ${vizsteps} progbar 10 13 z $(xhi) $(ylo-0.5) $(zlo+0.5*(zhi-zlo)) $(lz-3.0) 0.5 v_prog 10 +fix obj all graphics/objects ${vizsteps} arrow 5 80.0 56.0 34.6 80.0 64.0 34.6 0.3 0.2 & + arrow 6 80.0 56.0 33.2 80.0 64.0 33.2 0.3 0.2 # combine the graphics into visualization -dump viz viz image ${vizsteps} hbonds-*.png element element size 800 800 zoom 1.7 view 90 0 & - fsaa yes ssao yes 12384 0.6 shiny 0.1 box no 0.1 bond atom 0.3 & - center s 0.5 0.5 0.4 axes no 0.5 0.1 & - compute hb1 const -0.4 0.4 compute hb2 const -0.4 0.4 & - fix label const 1 0 fix obj type 0.0 0.0 fix graphics element 1 0.1 +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.65 0.45 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 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 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 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 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; diff --git a/src/GRAPHICS/dump_image.cpp b/src/GRAPHICS/dump_image.cpp index e943e11b478..e1c0b560399 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,18 @@ 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.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; + } } m += size_one; @@ -1424,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) { @@ -1440,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) { @@ -1458,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 @@ -1689,7 +1710,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 +1841,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 +1859,31 @@ 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->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}}; + // 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 + 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 +1941,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 +1978,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}; } } @@ -2528,12 +2579,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) { diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp index e697663a7a3..a66a461ca1b 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; @@ -877,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) { @@ -888,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); @@ -1085,9 +1088,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; @@ -1118,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) { @@ -1129,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; @@ -1142,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); } } @@ -1184,9 +1191,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; @@ -1334,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() * @@ -1546,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) { @@ -1557,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]; @@ -1795,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); @@ -1812,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; @@ -1824,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"); } } @@ -2066,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() * @@ -2495,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++; } diff --git a/src/group.cpp b/src/group.cpp index 5eb9bf9de95..4ee2dd79c3d 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]; } @@ -667,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) @@ -703,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); 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); } } 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]; 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); } }