Merge pull request #3910 from akohlmey/add-slideshow

Add slideshow feature to LAMMPS GUI
This commit is contained in:
Axel Kohlmeyer
2023-08-31 21:35:45 -04:00
committed by GitHub
40 changed files with 824 additions and 444 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 86 KiB

View File

@ -17,7 +17,7 @@
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>LAMMPS</string>
<string>LAMMPS_GUI</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>

View File

@ -9,7 +9,7 @@ of the available packages.
The following individual commands are included:
binary2txt lammps-gui lmp msi2lmp phana stl_bin2txt
After copying the lammps-gui folder into your Applications folder, please follow
After copying the LAMMPS_GUI folder into your Applications folder, please follow
these steps:
1. Open the Terminal app
@ -23,7 +23,7 @@ these steps:
3. Add the following lines to the end of the file, save it, and close the editor
LAMMPS_INSTALL_DIR=/Applications/LAMMPS.app/Contents
LAMMPS_INSTALL_DIR=/Applications/LAMMPS_GUI.app/Contents
LAMMPS_POTENTIALS=${LAMMPS_INSTALL_DIR}/share/lammps/potentials
LAMMPS_BENCH_DIR=${LAMMPS_INSTALL_DIR}/share/lammps/bench
MSI2LMP_LIBRARY=${LAMMPS_INSTALL_DIR}/share/lammps/frc_files
@ -38,9 +38,9 @@ these steps:
the changes from .zprofile automatically.
Note: the above assumes you use the default shell (zsh) that comes with
MacOS. If you customized MacOS to use a different shell, you'll need to modify
that shell's init file (.cshrc, .bashrc, etc.) instead with appropiate commands
to modify the same environment variables.
MacOS. If you customized MacOS to use a different shell, you'll need to
modify that shell's init file (.cshrc, .bashrc, etc.) instead with
appropiate commands to modify the same environment variables.
5. Try running LAMMPS (which might fail, see step 7)
@ -50,10 +50,10 @@ these steps:
lammps-gui ${LAMMPS_BENCH_DIR}/in.rhodo
Depending on the size and resolution of your screen, the fonts may
be too small to read. This can be adjusted by setting the environment
variable QT_FONT_DPI. The default value would be 72, so to increase
the fonts by a third one can add to the .zprofile file the line
Depending on the size and resolution of your screen, the fonts may be too
small to read. This can be adjusted by setting the environment variable
QT_FONT_DPI. The default value would be 72, so to increase the fonts by a
third, one can add to the .zprofile file the line
export QT_FONT_DPI=96
@ -61,9 +61,9 @@ these steps:
7. Give permission to execute the commands (lmp, lammps-gui, msi2lmp, binary2txt, phana, stl_bin2txt)
MacOS will likely block the initial run of the executables, since they
were downloaded from the internet and are missing a known signature from an
identified developer. Go to "Settings" and search for "Security settings". It
should display a message that an executable like "lmp" was blocked. Press
MacOS will likely block the initial run of the executables, since they were
downloaded from the internet and are missing a known signature from an
identified developer. Go to "Settings" and search for "Security settings".
It should display a message that an executable like "lmp" was blocked. Press
"Open anyway", which might prompt you for your admin credentials. Afterwards
"lmp" and the other executables should work as expected.

View File

@ -4,7 +4,7 @@ APP_NAME=lammps-gui
DESTDIR=${PWD}/../LAMMPS_GUI
echo "Delete old files, if they exist"
rm -rf ${DESTDIR} ../LAMMPS-Linux-amd64.tar.gz
rm -rf ${DESTDIR} ../LAMMPS_GUI-Linux-amd64.tar.gz
echo "Create staging area for deployment and populate"
DESTDIR=${DESTDIR} cmake --install . --prefix "/"
@ -69,7 +69,7 @@ do \
done
pushd ..
tar -czvvf LAMMPS-Linux-amd64.tar.gz LAMMPS_GUI
tar -czvvf LAMMPS_GUI-Linux-amd64.tar.gz LAMMPS_GUI
popd
echo "Cleanup dir"

View File

@ -3,7 +3,7 @@
APP_NAME=lammps-gui
echo "Delete old files, if they exist"
rm -f ${APP_NAME}.dmg ${APP_NAME}-rw.dmg LAMMPS-macOS-multiarch.dmg
rm -f ${APP_NAME}.dmg ${APP_NAME}-rw.dmg LAMMPS_GUI-macOS-multiarch.dmg
echo "Create initial dmg file with macdeployqt"
macdeployqt lammps-gui.app -dmg
@ -22,8 +22,8 @@ ln -s /Applications .
mv ${APP_NAME}.app/Contents/Resources/README.txt .
mkdir .background
mv ${APP_NAME}.app/Contents/Resources/LAMMPS_DMG_Background.png .background/background.png
mv ${APP_NAME}.app LAMMPS.app
cd LAMMPS.app/Contents
mv ${APP_NAME}.app LAMMPS_GUI.app
cd LAMMPS_GUI.app/Contents
echo "Attach icons to LAMMPS console and GUI executables"
echo "read 'icns' (-16455) \"Resources/lammps.icns\";" > icon.rsrc
@ -75,7 +75,7 @@ echo '
set statusbar visible to false
set toolbar visible to false
set the bounds to { 100, 40, 868, 640 }
set position of item "'LAMMPS'.app" to { 190, 216 }
set position of item "'LAMMPS_GUI'.app" to { 190, 216 }
set position of item "Applications" to { 576, 216 }
set position of item "README.txt" to { 190, 400 }
end tell
@ -96,12 +96,12 @@ sync
echo "Unmount modified disk image and convert to compressed read-only image"
hdiutil detach "${DEVICE}"
hdiutil convert "${APP_NAME}-rw.dmg" -format UDZO -o "LAMMPS-macOS-multiarch.dmg"
hdiutil convert "${APP_NAME}-rw.dmg" -format UDZO -o "LAMMPS_GUI-macOS-multiarch.dmg"
echo "Attach icon to .dmg file"
echo "read 'icns' (-16455) \"lammps-gui.app/Contents/Resources/lammps.icns\";" > icon.rsrc
Rez -a icon.rsrc -o LAMMPS-macOS-multiarch.dmg
SetFile -a C LAMMPS-macOS-multiarch.dmg
Rez -a icon.rsrc -o LAMMPS_GUI-macOS-multiarch.dmg
SetFile -a C LAMMPS_GUI-macOS-multiarch.dmg
rm icon.rsrc
echo "Delete temporary disk images"

View File

@ -1,7 +1,7 @@
# CMake script to be run post installation to build zipped package
# clean up old zipfile and deployment tree
file(REMOVE LAMMPS-Win10-amd64.zip)
file(REMOVE LAMMPS_GUI-Win10-amd64.zip)
file(REMOVE_RECURSE LAMMPS_GUI)
file(RENAME ${INSTNAME} LAMMPS_GUI)
@ -22,7 +22,7 @@ execute_process(COMMAND cmd.exe /c qtdeploy.bat COMMAND_ECHO STDERR)
file(REMOVE qtdeploy.bat)
# create zip archive
file(WRITE makearchive.ps1 "Compress-Archive -Path LAMMPS_GUI -CompressionLevel Optimal -DestinationPath LAMMPS-Win10-amd64.zip")
file(WRITE makearchive.ps1 "Compress-Archive -Path LAMMPS_GUI -CompressionLevel Optimal -DestinationPath LAMMPS_GUI-Win10-amd64.zip")
execute_process(COMMAND powershell -ExecutionPolicy Bypass -File makearchive.ps1)
file(REMOVE makearchive.ps1)
file(REMOVE_RECURSE LAMMPS_GUI)

View File

@ -1,7 +1,7 @@
Using the LAMMPS GUI
====================
This document describes **LAMMPS GUI version 1.3**.
This document describes **LAMMPS GUI version 1.4**.
-----
@ -168,7 +168,7 @@ Chart Window
------------
By default, when starting a run, a "Chart Window" will open that displays charts
of thermodynamic output of the LAMMPS calculation as shown below.
of the thermodynamic output of the LAMMPS calculation as shown below.
.. image:: JPG/lammps-gui-chart.png
:align: center
@ -191,6 +191,22 @@ unless the format, number, or names of output columns are changed or the
current time step is reset with :doc:`reset_timestep <reset_timestep>`
or a :doc:`clear <clear>` command is issued.
Image Slide Show
----------------
By default, in case the LAMMPS input contains a :doc:`dump image
<dump_image>` command, a "Slide Show" window will open which loads and
displays the images created by LAMMPS as they are written.
.. image:: JPG/lammps-gui-slideshow.png
:align: center
:scale: 50%
The various buttons at the bottom right of the window allow to either
single step through the list of images or play an animation (as a
continuous loop or once from first to last). It is also possible to
zoom in or zoom out.
Variable Info
-------------
@ -213,7 +229,7 @@ via the "Set Variables..." dialog from the ``Run`` menu.
Viewing Snapshot Images
-----------------------
By selecting the ``View Image`` entry in the ``Run`` menu, by hitting
By selecting the ``Create Image`` entry in the ``Run`` menu, by hitting
the `Ctrl-I` (`Command-I` on macOS) hotkey, or by clicking on the
"palette" button in the status bar, LAMMPS GUI will issue a
:doc:`write_dump image <dump_image>` command and read the resulting
@ -347,7 +363,7 @@ not defined as far as the built-in parser can detect them. New rows for
additional variables can be added through the ``Add Row`` button and
existing rows may be deleted by clicking on the ``X`` icons on the right.
The ``View Image`` entry will send a :doc:`dump image <dump_image>`
The ``Create Image`` entry will send a :doc:`dump image <dump_image>`
command to the LAMMPS instance, read the resulting file, and show it in
an ``Image Viewer`` window.
@ -389,13 +405,13 @@ and looks of the LAMMPS GUI application. The settings are grouped
and each group is displayed within a tab.
.. |guiprefs1| image:: JPG/lammps-gui-prefs-general.png
:width: 25%
:width: 32%
.. |guiprefs2| image:: JPG/lammps-gui-prefs-accel.png
:width: 25%
:width: 32%
.. |guiprefs3| image:: JPG/lammps-gui-prefs-image.png
:width: 25%
:width: 32%
|guiprefs1| |guiprefs2| |guiprefs3|
@ -405,7 +421,7 @@ General Settings:
- *Echo input to log:* when checked, all input commands, including
variable expansions, will be echoed to the log window. This is
equivalent to using `-echo screen` at the command line. There is no
log *file* produced since it always uses `-log none`.
log *file* produced by default, since LAMMPS GUI uses `-log none`.
- *Include citation details:* when checked full citation info will be
included to the log window. This is equivalent to using `-cite
screen` on the command line.
@ -414,6 +430,9 @@ General Settings:
- *Show chart window by default:* when checked, the thermodynamic
output of a LAMMPS run will be collected and displayed in a chart
window as line graphs.
- *Show slide show window by default:* when checked, a slide show
window will be shown with images from a dump image command, if
present, in the LAMMPS input.
- *Replace log window on new run:* when checked, an existing log
window will be replaced on a new LAMMPS run, otherwise each run will
create a new log window.
@ -481,54 +500,52 @@ instead of Ctrl/Control).
- Function
- Hotkey
- Function
- Hotkey
- Function
* - Ctrl+N
- New File
- Ctrl+Z
- Undo edit
- Ctrl+Enter
- Run LAMMPS
- Ctrl+Shift+A
- About LAMMPS
* - Ctrl+O
- Open File
- Ctrl+Shift+Z
- Redo edit
- Ctrl+/
- Stop Active Run
- Ctrl+Shift+H
- Quick Help
* - CTRL+S
- Save File
- Ctrl+C
- Copy text
- Ctrl+Shift+V
- Set Variables
- Ctrl+Shift+G
- LAMMPS GUI Howto
* - Ctrl+Shift+S
- Save File As
- Ctrl+X
- Cut text
- Ctrl+I
- Snapshot Image
- Ctrl+Shift+M
- LAMMPS Manual
* - Ctrl+Q
- Quit
- Ctrl+V
- Paste text
- Ctrl+P
- Preferences
- Ctrl+?
- Context Help
- Ctrl-L
- Slide Show
* - Ctrl-W
- Close Window
- Ctrl-A
- Select All
- Ctrl-Shift-Enter
- Run Current File
- Ctrl+P
- Preferences
* - Ctrl+Shift+A
- About LAMMPS
- Ctrl+Shift+H
- Quick Help
- Ctrl+Shift+G
- LAMMPS GUI Howto
* - Ctrl+Shift+M
- LAMMPS Manual
- Ctrl+?
- Context Help
- Ctrl-Shift-W
- Show Variables

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -1506,6 +1506,7 @@ Im
imageint
Imageint
Imagemagick
imagename
imd
Impey
impl

View File

@ -36,6 +36,8 @@
#include "memory.h"
#include "modify.h"
#include "molecule.h"
#include "output.h"
#include "thermo.h"
#include "tokenizer.h"
#include "update.h"
#include "variable.h"
@ -77,18 +79,10 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) :
// set filetype based on filename suffix
int n = strlen(filename);
if (strlen(filename) > 4 && strcmp(&filename[n-4],".jpg") == 0)
if (utils::strmatch(filename, "\\.jpg$") || utils::strmatch(filename, "\\.JPG$")
|| utils::strmatch(filename, "\\.jpeg$") || utils::strmatch(filename, "\\.JPEG$"))
filetype = JPG;
else if (strlen(filename) > 4 && strcmp(&filename[n-4],".JPG") == 0)
filetype = JPG;
else if (strlen(filename) > 5 && strcmp(&filename[n-5],".jpeg") == 0)
filetype = JPG;
else if (strlen(filename) > 5 && strcmp(&filename[n-5],".JPEG") == 0)
filetype = JPG;
else if (strlen(filename) > 4 && strcmp(&filename[n-4],".png") == 0)
filetype = PNG;
else if (strlen(filename) > 4 && strcmp(&filename[n-4],".PNG") == 0)
else if (utils::strmatch(filename, "\\.png$") || utils::strmatch(filename, "\\.PNG$"))
filetype = PNG;
else filetype = PPM;
@ -481,6 +475,7 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) :
DumpImage::~DumpImage()
{
delete image;
output->thermo->set_image_fname("");
delete[] diamtype;
delete[] diamelement;
@ -792,6 +787,12 @@ void DumpImage::write()
if (multifile) {
fclose(fp);
fp = nullptr;
// cache last dump image filename for access through library interface.
// update only *after* the file has been written so there will be no invalid read.
// have to recreate the substitution done within openfile().
output->thermo->set_image_fname(utils::star_subst(filename, update->ntimestep, padflag));
}
}
}

View File

@ -69,9 +69,8 @@ void DumpMovie::init_style()
{
// initialize image style circumventing multifile check
multifile = 1;
multifile_override = 1;
DumpImage::init_style();
multifile = 0;
}
/* ---------------------------------------------------------------------- */

View File

@ -822,6 +822,10 @@ argument string.
- line number (0-based) of current line in current file or buffer
- pointer to int
- no
* - imagename
- file name of the last :doc:`dump image <dump_image>` file written
- pointer to 0-terminated const char array
- no
* - step
- timestep when the last thermo output was generated or -1
- pointer to bigint
@ -866,6 +870,9 @@ void *lammps_last_thermo(void *handle, const char *what, int index)
} else if (strcmp(what, "line") == 0) {
val = (void *) th->get_line();
} else if (strcmp(what, "imagename") == 0) {
val = (void *) th->get_image_fname();
} else if (strcmp(what, "step") == 0) {
val = (void *) th->get_timestep();
@ -2489,9 +2496,9 @@ string, otherwise 1.
int lammps_variable_info(void *handle, int idx, char *buffer, int buf_size) {
auto lmp = (LAMMPS *) handle;
Info info(lmp);
auto varinfo = info.get_variable_info(idx);
if ((idx >= 0) && (idx < lmp->input->variable->nvar)) {
auto varinfo = info.get_variable_info(idx);
strncpy(buffer, varinfo.c_str(), buf_size);
return 1;
}

View File

@ -796,9 +796,12 @@ void ReadRestart::header()
} else if (flag == ATOM_ID) {
atom->tag_enable = read_int();
} else if (flag == ATOM_MAP_STYLE) {
atom->map_style = read_int();
// we should be able to enable an atom map, even
// if the simulation in the restart didn't use one
int itmp = read_int();
if (atom->map_user == Atom::MAP_NONE) atom->map_style = itmp;
} else if (flag == ATOM_MAP_USER) {
atom->map_user = read_int();
int itmp = read_int(); // ignored
} else if (flag == ATOM_SORTFREQ) {
atom->sortfreq = read_int();
} else if (flag == ATOM_SORTBIN) {

View File

@ -113,6 +113,7 @@ Thermo::Thermo(LAMMPS *_lmp, int narg, char **arg) :
flushflag = 0;
ntimestep = -1;
nline = -1;
image_fname.clear();
// set style and corresponding lineflag
// custom style builds its own line of keywords, including wildcard expansion

View File

@ -42,14 +42,17 @@ class Thermo : protected Pointers {
void compute(int);
int evaluate_keyword(const std::string &, double *);
// for accessing cached thermo data
const int *get_nfield() const { return &nfield; }
// for accessing cached thermo and related data
const int *get_line() const { return &nline; }
const char *get_image_fname() const { return image_fname.c_str(); }
const int *get_nfield() const { return &nfield; }
const bigint *get_timestep() const { return &ntimestep; }
const std::vector<multitype> &get_fields() const { return field_data; }
const std::vector<std::string> &get_keywords() const { return keyword; }
void set_line(int _nline) { nline = _nline; }
void set_image_fname(const std::string &fname) { image_fname = fname; }
private:
int nfield, nfield_initial;
@ -75,6 +78,7 @@ class Thermo : protected Pointers {
bigint natoms;
bigint ntimestep;
int nline;
std::string image_fname;
// data used by routines that compute single values
int ivalue; // integer value to print

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.16)
project(lammps-gui VERSION 1.3.1 LANGUAGES CXX)
project(lammps-gui VERSION 1.4.1 LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
@ -72,17 +72,17 @@ find_package(Qt5 5.12 REQUIRED COMPONENTS Widgets Charts)
set(PROJECT_SOURCES
main.cpp
lammpsgui.cpp
lammpsgui.h
lammpsgui.ui
chartviewer.cpp
chartviewer.h
codeeditor.cpp
codeeditor.h
highlighter.cpp
highlighter.h
imageviewer.cpp
imageviewer.h
chartviewer.cpp
chartviewer.h
lammpsgui.cpp
lammpsgui.h
lammpsgui.ui
lammpsrunner.h
lammpswrapper.cpp
lammpswrapper.h
@ -93,6 +93,8 @@ set(PROJECT_SOURCES
preferences.h
setvariables.cpp
setvariables.h
slideshow.h
slideshow.cpp
stdcapture.cpp
${PLUGIN_LOADER_SRC}
${ICON_RC_FILE}

View File

@ -2,12 +2,8 @@ LAMMPS-GUI TODO list:
# Short term goals
- rewrite syntax highlighting to be line oriented instead of word oriented.
handle first part of line based on regular expressions, then advance and only highlight strings and numbers.
handle "&" continuation and multiline strings with """ like C style comments in Qt docs example
- add "syntax check" with enabled "-skiprun" flag
- switch input file editor to read-only while loop is running
- add slideshow of images from dump image commands in the input
# Long term ideas
- rewrite entire application to build the App and its layout manually

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -13,242 +13,220 @@
#include "highlighter.h"
Highlighter::Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent)
Highlighter::Highlighter(QTextDocument *parent) :
QSyntaxHighlighter(parent),
isLattice1(QStringLiteral("^\\s*(units|atom_style|change_box|dielectric|dimension)\\s+(\\S+)")),
isLattice2(QStringLiteral("^\\s*(lattice|region|create_box|create_atoms|delete_atoms|displace_"
"atoms)\\s+(\\S+)\\s+(\\S+)")),
isLattice3(QStringLiteral("^\\s*(boundary|replicate)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)")),
isOutput1(QStringLiteral("^\\s*(echo|log|write_data|write_coeff|write_restart|restart|info|"
"thermo|print|thermo_style|"
"timer|pair_write|bond_write|angle_write|dihedral_write)\\s+(\\S+)")),
isOutput2(QStringLiteral("^\\s*(write_dump|shell|thermo_modify)\\s+(\\S+)\\s+(\\S+)")),
isRead(QStringLiteral("^\\s*(include|read_restart|read_data|read_dump|molecule)")),
isStyle(QStringLiteral("^\\s*(fix|compute|dump)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)")),
isForce(QStringLiteral(
"^\\s*(pair_style|bond_style|angle_style|dihedral_style|improper_style|kspace_style|pair_"
"coeff|angle_coeff|bond_coeff|dihedral_coeff|improper_coeff)\\s+(\\S+)")),
isDefine(QStringLiteral("^\\s*(group|variable|python|set|group2ndx|ndx2group|kim|kim_query|mdi)"
"\\s+(\\S+)\\s+(\\S+)")),
isUndo(QStringLiteral("^\\s*(unfix|uncompute|undump|label|jump|next)\\s+(\\S+)")),
isParticle(QStringLiteral("^\\s*(pair_modify|mass|velocity|create_bonds|delete_"
"bonds|kspace_modify|labelmap|atom_modify)\\s+(\\S+)")),
isSetup(QStringLiteral(
"^\\s*(min_style|min_modify|run_style|timestep|neighbor|neigh_modify|suffix|special_bonds|"
"balance|box|clear|plugin|quit|comm_modify|comm_style|newton|package|partition|processors|"
"reset_atoms|reset_ids|reset_timestep|dump_modify|fix_modify|compute_modify)")),
isRun(QStringLiteral("^\\s*(minimize|minimize/kk|run|rerun|tad|neb|neb/spin|prd|server|temper/"
"npt|temper/grem|temper|message|hyper|dynamical_matrix|dynamical_matrix/"
"kk|third_order|third_order/kk|fitpod)")),
isVariable(QStringLiteral("\\s+(\\$[a-z]|\\${[^} ]+}|\\$\\(\\S+\\))")),
isReference(
QStringLiteral("\\s+(c_\\S+|C_\\S+|f_\\S+|F_\\S+|i_\\S+|i2_\\S+|d_\\S+|d2_\\S+|v_\\S+)")),
isNumber1(QStringLiteral("(^|\\s+)[0-9:*]+")), // integer and integer ranges
isNumber2(QStringLiteral("(^|\\s+)[0-9]+\\.[0-9]*[edED]?[-+]?[0-9]*")), // floating point 1
isNumber3(QStringLiteral("(^|\\s+)[0-9]*\\.[0-9]+[edED]?[-+]?[0-9]*")), // floating point 2
isNumber4(QStringLiteral("(^|\\s+)[0-9]+([edED][-+]?[0-9]+)?")), // floating point 3
isSpecial(
QStringLiteral("(\\s\\+?-?INF|\\sEDGE|\\sNULL|\\sSELF|if\\s|then\\s|else\\s|elif\\s)")),
isContinue(QStringLiteral("&$")), isComment(QStringLiteral("#.*")),
isQuotedComment(QStringLiteral("(\".*#.*\"|'.*#.*')")),
isTriple(QStringLiteral("[^\"]*\"\"\"[^\"]*")),
isString(QStringLiteral("(\".+?\"|'.+?'|\"\"\".*\"\"\")")), in_triple(false)
{
HighlightingRule rule;
formatNumber.setForeground(Qt::blue);
formatString.setForeground(Qt::darkGreen);
formatString.setFontWeight(QFont::Normal);
formatComment.setForeground(Qt::red);
formatSpecial.setForeground(Qt::darkMagenta);
formatSpecial.setFontWeight(QFont::Bold);
formatParticle.setForeground(Qt::darkRed);
formatParticle.setFontWeight(QFont::Bold);
formatRun.setForeground(Qt::darkBlue);
formatRun.setFontWeight(QFont::Bold);
formatVariable.setForeground(Qt::darkGray);
formatVariable.setFontWeight(QFont::Bold);
outputFormat.setForeground(Qt::darkYellow);
outputFormat.setFontWeight(QFont::Bold);
readFormat.setForeground(Qt::magenta);
readFormat.setFontWeight(QFont::Bold);
latticeFormat.setForeground(Qt::darkGreen);
latticeFormat.setFontWeight(QFont::Bold);
particleFormat.setForeground(Qt::darkRed);
particleFormat.setFontWeight(QFont::Bold);
setupFormat.setForeground(Qt::darkCyan);
setupFormat.setFontWeight(QFont::Bold);
runFormat.setForeground(Qt::darkBlue);
runFormat.setFontWeight(QFont::Bold);
defineFormat.setForeground(Qt::darkMagenta);
defineFormat.setFontWeight(QFont::Bold);
numberFormat.setForeground(Qt::blue);
commentFormat.setForeground(Qt::red);
stringFormat.setForeground(Qt::darkGreen);
stringFormat.setFontWeight(QFont::Normal);
const QString output_keywords[] = {
QStringLiteral("^\\s*log\\W"), QStringLiteral("^\\s*write_data\\W"),
QStringLiteral("^\\s*write_dump\\W"), QStringLiteral("^\\s*write_coeff\\W"),
QStringLiteral("^\\s*info\\W"), QStringLiteral("^\\s*shell\\W"),
QStringLiteral("^\\s*write_restart\\W"), QStringLiteral("^\\s*restart\\W"),
QStringLiteral("^\\s*dump\\W"), QStringLiteral("^\\s*undump\\W"),
QStringLiteral("^\\s*thermo\\W"), QStringLiteral("^\\s*thermo_modify\\W"),
QStringLiteral("^\\s*thermo_style\\W"), QStringLiteral("^\\s*print\\W"),
QStringLiteral("^\\s*timer\\W")};
for (const QString &pattern : output_keywords) {
rule.pattern = QRegularExpression(pattern);
rule.format = outputFormat;
highlightingRules.append(rule);
}
const QString read_keywords[] = {
QStringLiteral("^\\s*include\\W"), QStringLiteral("^\\s*read_restart\\W"),
QStringLiteral("^\\s*read_data\\W"), QStringLiteral("^\\s*read_dump\\W"),
QStringLiteral("^\\s*molecule\\W")};
for (const QString &pattern : read_keywords) {
rule.pattern = QRegularExpression(pattern);
rule.format = readFormat;
highlightingRules.append(rule);
}
const QString lattice_keywords[] = {
QStringLiteral("^\\s*boundary\\W"), QStringLiteral("^\\s*units\\W"),
QStringLiteral("^\\s*atom_style\\W"), QStringLiteral("^\\s*lattice\\W"),
QStringLiteral("^\\s*region\\W"), QStringLiteral("^\\s*create_box\\W"),
QStringLiteral("^\\s*create_atoms\\W"), QStringLiteral("^\\s*dielectric\\W"),
QStringLiteral("^\\s*delete_atoms\\W"), QStringLiteral("^\\s*displace_atoms\\W"),
QStringLiteral("^\\s*change_box\\W"), QStringLiteral("^\\s*dimension\\W"),
QStringLiteral("^\\s*replicate\\W")};
for (const QString &pattern : lattice_keywords) {
rule.pattern = QRegularExpression(pattern);
rule.format = latticeFormat;
highlightingRules.append(rule);
}
const QString particle_keywords[] = {
QStringLiteral("^\\s*pair_coeff\\W"), QStringLiteral("^\\s*pair_style\\W"),
QStringLiteral("^\\s*pair_modify\\W"), QStringLiteral("^\\s*pair_write\\W"),
QStringLiteral("^\\s*mass\\W"), QStringLiteral("^\\s*velocity\\W"),
QStringLiteral("^\\s*angle_coeff\\W"), QStringLiteral("^\\s*angle_style\\W"),
QStringLiteral("^\\s*angle_write\\W"), QStringLiteral("^\\s*atom_modify\\W"),
QStringLiteral("^\\s*atom_style\\W"), QStringLiteral("^\\s*bond_coeff\\W"),
QStringLiteral("^\\s*bond_style\\W"), QStringLiteral("^\\s*bond_write\\W"),
QStringLiteral("^\\s*create_bonds\\W"), QStringLiteral("^\\s*delete_bonds\\W"),
QStringLiteral("^\\s*kspace_style\\W"), QStringLiteral("^\\s*kspace_modify\\W"),
QStringLiteral("^\\s*dihedral_style\\W"), QStringLiteral("^\\s*dihedral_coeff\\W"),
QStringLiteral("^\\s*dihedral_write\\W"), QStringLiteral("^\\s*improper_style\\W"),
QStringLiteral("^\\s*improper_coeff\\W"), QStringLiteral("^\\s*labelmap\\W")};
for (const QString &pattern : particle_keywords) {
rule.pattern = QRegularExpression(pattern);
rule.format = particleFormat;
highlightingRules.append(rule);
}
const QString setup_keywords[] = {QStringLiteral("^\\s*min_style\\W"),
QStringLiteral("^\\s*min_modify\\W"),
QStringLiteral("^\\s*run_style\\W"),
QStringLiteral("^\\s*timestep\\W"),
QStringLiteral("^\\s*neighbor\\W"),
QStringLiteral("^\\s*neigh_modify\\W"),
QStringLiteral("^\\s*suffix\\W"),
QStringLiteral("^\\s*special_bonds\\W"),
QStringLiteral("^\\s*balance\\W"),
QStringLiteral("^\\s*box\\W"),
QStringLiteral("^\\s*clear\\W"),
QStringLiteral("^\\s*comm_modify\\W"),
QStringLiteral("^\\s*comm_style\\W"),
QStringLiteral("^\\s*newton\\W"),
QStringLiteral("^\\s*package\\W"),
QStringLiteral("^\\s*processors\\W"),
QStringLiteral("^\\s*reset_atoms\\W"),
QStringLiteral("^\\s*dump_modify\\W"),
QStringLiteral("^\\s*reset_ids\\W"),
QStringLiteral("^\\s*reset_timestep\\W"),
QStringLiteral("^\\s*label\\W"),
QStringLiteral("^\\s*jump\\W"),
QStringLiteral("^\\s*next\\W"),
QStringLiteral("^\\s*loop\\W")
};
for (const QString &pattern : setup_keywords) {
rule.pattern = QRegularExpression(pattern);
rule.format = setupFormat;
highlightingRules.append(rule);
}
const QString run_keywords[] = {QStringLiteral("^\\s*minimize\\W"),
QStringLiteral("^\\s*minimize/kk\\W"),
QStringLiteral("^\\s*run\\W"),
QStringLiteral("^\\s*rerun\\W"),
QStringLiteral("^\\s*tad\\W"),
QStringLiteral("^\\s*neb\\W"),
QStringLiteral("^\\s*neb/spin\\W"),
QStringLiteral("^\\s*prd\\W"),
QStringLiteral("^\\s*quit\\W"),
QStringLiteral("^\\s*server\\W"),
QStringLiteral("^\\s*temper/npt\\W"),
QStringLiteral("^\\s*temper/grem\\W"),
QStringLiteral("^\\s*temper\\W"),
QStringLiteral("^\\s*message\\W"),
QStringLiteral("^\\s*hyper\\W"),
QStringLiteral("^\\s*dynamical_matrix\\W"),
QStringLiteral("^\\s*dynamical_matrix/kk\\W"),
QStringLiteral("^\\s*third_order\\W"),
QStringLiteral("^\\s*third_order/kk\\W"),
QStringLiteral("^\\s*fitpod\\W"),
QStringLiteral("^\\s*if\\W"),
QStringLiteral("^\\s*then\\W"),
QStringLiteral("^\\s*elif\\W"),
QStringLiteral("^\\s*else\\W")};
for (const QString &pattern : run_keywords) {
rule.pattern = QRegularExpression(pattern);
rule.format = runFormat;
highlightingRules.append(rule);
}
const QString define_keywords[] = {QStringLiteral("^\\s*variable\\W"),
QStringLiteral("^\\s*group\\W"),
QStringLiteral("^\\s*compute\\W"),
QStringLiteral("^\\s*python\\W"),
QStringLiteral("^\\s*set\\W"),
QStringLiteral("^\\s*uncompute\\W"),
QStringLiteral("^\\s*kim_query\\W"),
QStringLiteral("^\\s*kim\\W"),
QStringLiteral("^\\s*group2ndx\\W"),
QStringLiteral("^\\s*ndx2group\\W"),
QStringLiteral("^\\s*compute_modify\\W"),
QStringLiteral("^\\s*fix_modify\\W"),
QStringLiteral("^\\s*fix\\W"),
QStringLiteral("^\\s*unfix\\W"),
QStringLiteral("^\\s*INF\\W"),
QStringLiteral("^\\s*EDGE\\W"),
QStringLiteral("^\\s*NULL\\W"),
QStringLiteral("^\\s*&\\s*$"),
QStringLiteral("^\\s*mdi\\W")};
for (const QString &pattern : define_keywords) {
rule.pattern = QRegularExpression(pattern);
rule.format = defineFormat;
highlightingRules.append(rule);
}
const QString number_keywords[] = {
QStringLiteral("(^|\\s+)[0-9:*]+"), // integer and integer ranges
QStringLiteral("(^|\\s+)[0-9]+\\.[0-9]*[edED]?[-+]?[0-9]*"), // floating point 1
QStringLiteral("(^|\\s+)[0-9]*\\.[0-9]+[edED]?[-+]?[0-9]*"), // floating point 2
QStringLiteral("(^|\\s+)[0-9]+([edED][-+]?[0-9]+)?") // floating point 3
};
for (const QString &pattern : number_keywords) {
rule.pattern = QRegularExpression(pattern);
rule.format = numberFormat;
highlightingRules.append(rule);
}
// comments, must come before strings but after other keywords.
rule.pattern = QRegularExpression("#.*");
rule.format = commentFormat;
highlightingRules.append(rule);
// strings, must come last so it overwrites other formatting
rule.pattern = QRegularExpression("(\".*\"|'.*')");
rule.format = stringFormat;
highlightingRules.append(rule);
formatOutput.setForeground(Qt::darkYellow);
formatOutput.setFontWeight(QFont::Bold);
formatRead.setForeground(Qt::magenta);
formatRead.setFontWeight(QFont::Bold);
formatLattice.setForeground(Qt::darkGreen);
formatLattice.setFontWeight(QFont::Bold);
formatSetup.setForeground(Qt::darkCyan);
formatSetup.setFontWeight(QFont::Bold);
}
void Highlighter::highlightBlock(const QString &text)
{
// clang-format off
auto style = QRegularExpression("^(fix|compute|dump|set)\\s+(\\w+)\\s+(\\S+)\\s+(\\S+)").match(text);
auto force = QRegularExpression("^(atom_style|pair_style|bond_style|angle_style|dihedral_style|improper_style|kspace_style)\\s+(\\S+)").match(text);
auto defs = QRegularExpression("^(group|variable)\\s+(\\S+)\\s+(\\S+)").match(text);
auto undo = QRegularExpression("^(unfix|uncompute|undump)\\s+(\\w+)").match(text);
// clang-format on
bool do_style = true;
bool do_force = true;
bool do_defs = true;
bool do_undo = true;
for (const HighlightingRule &rule : qAsConst(highlightingRules)) {
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
while (matchIterator.hasNext()) {
QRegularExpressionMatch match = matchIterator.next();
// special treatment for fix/compute/dump styles etc.
if (style.hasMatch() && do_style) {
setFormat(style.capturedStart(1), style.capturedLength(1), defineFormat);
setFormat(style.capturedStart(2), style.capturedLength(2), numberFormat);
setFormat(style.capturedStart(3), style.capturedLength(3), stringFormat);
setFormat(style.capturedStart(4), style.capturedLength(4), runFormat);
do_style = false;
// special treatment for force styles styles
} else if (force.hasMatch() && do_force) {
setFormat(force.capturedStart(1), force.capturedLength(1), particleFormat);
setFormat(force.capturedStart(2), force.capturedLength(2), runFormat);
do_force = false;
// special treatment for undo commands
} else if (undo.hasMatch() && do_undo) {
setFormat(undo.capturedStart(1), undo.capturedLength(1), defineFormat);
setFormat(undo.capturedStart(2), undo.capturedLength(2), stringFormat);
do_undo = false;
// special treatment for some definitions
} else if (defs.hasMatch() && do_defs) {
setFormat(defs.capturedStart(1), defs.capturedLength(1), particleFormat);
setFormat(defs.capturedStart(2), defs.capturedLength(2), stringFormat);
setFormat(defs.capturedStart(3), defs.capturedLength(3), runFormat);
do_defs = false;
} else {
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
}
// nothing to do for empty lines
if (text.isEmpty()) return;
auto match = isLattice1.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatLattice);
setFormat(match.capturedStart(2), match.capturedLength(2), formatRun);
}
match = isLattice2.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatLattice);
setFormat(match.capturedStart(2), match.capturedLength(2), formatString);
setFormat(match.capturedStart(3), match.capturedLength(3), formatRun);
}
match = isLattice3.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatLattice);
setFormat(match.capturedStart(2), match.capturedLength(2), formatString);
setFormat(match.capturedStart(3), match.capturedLength(3), formatString);
setFormat(match.capturedStart(4), match.capturedLength(4), formatString);
}
match = isOutput1.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatOutput);
setFormat(match.capturedStart(2), match.capturedLength(2), formatString);
}
match = isOutput2.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatOutput);
setFormat(match.capturedStart(2), match.capturedLength(2), formatString);
setFormat(match.capturedStart(3), match.capturedLength(3), formatRun);
}
match = isRead.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatRead);
setFormat(match.capturedStart(2), match.capturedLength(2), formatString);
}
match = isStyle.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatParticle);
setFormat(match.capturedStart(2), match.capturedLength(2), formatNumber);
setFormat(match.capturedStart(3), match.capturedLength(3), formatString);
setFormat(match.capturedStart(4), match.capturedLength(4), formatRun);
}
match = isForce.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatParticle);
setFormat(match.capturedStart(2), match.capturedLength(2), formatRun);
}
match = isUndo.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatSpecial);
setFormat(match.capturedStart(2), match.capturedLength(2), formatString);
}
match = isDefine.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatParticle);
setFormat(match.capturedStart(2), match.capturedLength(2), formatString);
setFormat(match.capturedStart(3), match.capturedLength(3), formatRun);
}
match = isParticle.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatParticle);
setFormat(match.capturedStart(2), match.capturedLength(2), formatString);
}
match = isSetup.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatSetup);
}
match = isRun.match(text);
if (match.hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), formatRun);
}
// numbers
QRegularExpression numbers[] = {isNumber1, isNumber2, isNumber3, isNumber4};
for (auto &number : numbers) {
auto num = number.globalMatch(text);
while (num.hasNext()) {
auto match = num.next();
setFormat(match.capturedStart(), match.capturedLength(), formatNumber);
}
}
// variables
auto vars = isVariable.globalMatch(text);
while (vars.hasNext()) {
auto match = vars.next();
setFormat(match.capturedStart(), match.capturedLength(), formatVariable);
}
// references
auto refs = isReference.globalMatch(text);
while (refs.hasNext()) {
auto match = refs.next();
setFormat(match.capturedStart(), match.capturedLength(), formatVariable);
}
// continuation character
auto multiline = isContinue.match(text);
if (multiline.hasMatch())
setFormat(multiline.capturedStart(0), multiline.capturedLength(0), formatSpecial);
// special keywords
auto special = isSpecial.globalMatch(text);
while (special.hasNext()) {
auto match = special.next();
setFormat(match.capturedStart(), match.capturedLength(), formatSpecial);
}
// comments, must come before strings but after other keywords.
auto comment = isComment.match(text);
if (comment.hasMatch() && !isQuotedComment.match(text).hasMatch() && !in_triple) {
setFormat(comment.capturedStart(0), comment.capturedLength(0), formatComment);
return;
}
// strings, must come last so they can overwrite other formatting
auto string = isString.globalMatch(text);
while (string.hasNext()) {
auto match = string.next();
setFormat(match.capturedStart(), match.capturedLength(), formatString);
}
auto triple = isTriple.match(text);
if (triple.hasMatch()) {
if (in_triple) {
in_triple = false;
setFormat(0, triple.capturedStart(0) + triple.capturedLength(0), formatString);
} else {
in_triple = true;
setFormat(triple.capturedStart(0), -1, formatString);
}
} else {
if (in_triple) setFormat(0, text.size(), formatString);
}
}
// Local Variables:
// c-basic-offset: 4

View File

@ -28,23 +28,27 @@ protected:
void highlightBlock(const QString &text) override;
private:
struct HighlightingRule {
QRegularExpression pattern;
QTextCharFormat format;
};
QVector<HighlightingRule> highlightingRules;
QRegularExpression isLattice1, isLattice2, isLattice3;
QRegularExpression isOutput1, isOutput2, isRead;
QTextCharFormat formatOutput, formatRead, formatLattice, formatSetup;
QRegularExpression isStyle, isForce, isDefine, isUndo;
QRegularExpression isParticle, isSetup, isRun;
QTextCharFormat formatParticle, formatRun, formatDefine;
QRegularExpression isVariable, isReference;
QTextCharFormat formatVariable;
QRegularExpression isNumber1, isNumber2, isNumber3, isNumber4;
QTextCharFormat formatNumber;
QRegularExpression isSpecial, isContinue;
QTextCharFormat formatSpecial;
QRegularExpression isComment;
QRegularExpression isQuotedComment;
QTextCharFormat formatComment;
QRegularExpression isTriple;
QRegularExpression isString;
QTextCharFormat formatString;
QTextCharFormat outputFormat;
QTextCharFormat readFormat;
QTextCharFormat latticeFormat;
QTextCharFormat particleFormat;
QTextCharFormat setupFormat;
QTextCharFormat runFormat;
QTextCharFormat defineFormat;
QTextCharFormat numberFormat;
QTextCharFormat stringFormat;
QTextCharFormat commentFormat;
int in_triple;
int startIndex;
};
#endif
// Local Variables:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -103,8 +103,10 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge
connect(xval, &QAbstractSpinBox::editingFinished, this, &ImageViewer::edit_size);
connect(yval, &QAbstractSpinBox::editingFinished, this, &ImageViewer::edit_size);
// workaround for incorrect highlight bug on macOS
auto *dummy = new QPushButton(QIcon(), "");
dummy->hide();
auto *dossao = new QPushButton(QIcon(":/hd-img.png"), "");
dossao->setCheckable(true);
dossao->setToolTip("Toggle SSAO rendering");
@ -190,6 +192,7 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge
mainLayout->addLayout(menuLayout);
mainLayout->addWidget(scrollArea);
mainLayout->addWidget(buttonBox);
setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
setWindowTitle(QString("Image Viewer: ") + QFileInfo(fileName).fileName());
createActions();
@ -207,9 +210,7 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge
resize(image.width() + 20, image.height() + 50);
scrollArea->setVisible(true);
fitToWindowAct->setEnabled(true);
updateActions();
if (!fitToWindowAct->isChecked()) imageLabel->adjustSize();
setLayout(mainLayout);
}
@ -464,30 +465,6 @@ void ImageViewer::saveAs()
void ImageViewer::copy() {}
void ImageViewer::zoomIn()
{
scaleImage(1.25);
}
void ImageViewer::zoomOut()
{
scaleImage(0.8);
}
void ImageViewer::normalSize()
{
imageLabel->adjustSize();
scaleFactor = 1.0;
}
void ImageViewer::fitToWindow()
{
bool fitToWindow = fitToWindowAct->isChecked();
scrollArea->setWidgetResizable(fitToWindow);
if (!fitToWindow) normalSize();
updateActions();
}
void ImageViewer::saveFile(const QString &fileName)
{
if (!fileName.isEmpty()) image.save(fileName);
@ -509,39 +486,12 @@ void ImageViewer::createActions()
QAction *exitAct = fileMenu->addAction("&Close", this, &QWidget::close);
exitAct->setIcon(QIcon(":/window-close.png"));
exitAct->setShortcut(QKeySequence::fromString("Ctrl+W"));
QMenu *viewMenu = menuBar->addMenu("&View");
zoomInAct = viewMenu->addAction("Image Zoom &In (25%)", this, &ImageViewer::zoomIn);
zoomInAct->setShortcut(QKeySequence::ZoomIn);
zoomInAct->setIcon(QIcon(":/gtk-zoom-in.png"));
zoomInAct->setEnabled(false);
zoomOutAct = viewMenu->addAction("Image Zoom &Out (25%)", this, &ImageViewer::zoomOut);
zoomOutAct->setShortcut(QKeySequence::ZoomOut);
zoomOutAct->setIcon(QIcon(":/gtk-zoom-out.png"));
zoomOutAct->setEnabled(false);
normalSizeAct = viewMenu->addAction("&Reset Image Size", this, &ImageViewer::normalSize);
normalSizeAct->setShortcut(QKeySequence::fromString("Ctrl+0"));
normalSizeAct->setIcon(QIcon(":/gtk-zoom-fit.png"));
normalSizeAct->setEnabled(false);
viewMenu->addSeparator();
fitToWindowAct = viewMenu->addAction("&Fit to Window", this, &ImageViewer::fitToWindow);
fitToWindowAct->setEnabled(false);
fitToWindowAct->setCheckable(true);
fitToWindowAct->setShortcut(QKeySequence::fromString("Ctrl+="));
}
void ImageViewer::updateActions()
{
saveAsAct->setEnabled(!image.isNull());
copyAct->setEnabled(!image.isNull());
zoomInAct->setEnabled(!fitToWindowAct->isChecked());
zoomOutAct->setEnabled(!fitToWindowAct->isChecked());
normalSizeAct->setEnabled(!fitToWindowAct->isChecked());
}
void ImageViewer::scaleImage(double factor)
@ -555,8 +505,6 @@ void ImageViewer::scaleImage(double factor)
adjustScrollBar(scrollArea->horizontalScrollBar(), factor);
adjustScrollBar(scrollArea->verticalScrollBar(), factor);
zoomInAct->setEnabled(scaleFactor < 3.0);
zoomOutAct->setEnabled(scaleFactor > 0.333);
}
void ImageViewer::adjustScrollBar(QScrollBar *scrollBar, double factor)

View File

@ -40,10 +40,6 @@ public:
private slots:
void saveAs();
void copy();
void zoomIn();
void zoomOut();
void normalSize();
void fitToWindow();
void edit_size();
void reset_view();

View File

@ -20,6 +20,7 @@
#include "logwindow.h"
#include "preferences.h"
#include "setvariables.h"
#include "slideshow.h"
#include "stdcapture.h"
#include "ui_lammpsgui.h"
@ -96,8 +97,8 @@ static bool has_exe(const QString &exe)
LammpsGui::LammpsGui(QWidget *parent, const char *filename) :
QMainWindow(parent), ui(new Ui::LammpsGui), highlighter(nullptr), capturer(nullptr),
status(nullptr), logwindow(nullptr), imagewindow(nullptr), chartwindow(nullptr),
logupdater(nullptr), dirstatus(nullptr), progress(nullptr), prefdialog(nullptr),
lammpsstatus(nullptr), varwindow(nullptr)
slideshow(nullptr), logupdater(nullptr), dirstatus(nullptr), progress(nullptr),
prefdialog(nullptr), lammpsstatus(nullptr), varwindow(nullptr)
{
// enforce using the plain ASCII C locale within the GUI.
QLocale::setDefault(QLocale("C"));
@ -239,6 +240,7 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) :
connect(ui->actionView_Log_Window, &QAction::triggered, this, &LammpsGui::view_log);
connect(ui->actionView_Graph_Window, &QAction::triggered, this, &LammpsGui::view_chart);
connect(ui->actionView_Image_Window, &QAction::triggered, this, &LammpsGui::view_image);
connect(ui->actionView_Slide_Show, &QAction::triggered, this, &LammpsGui::view_slides);
connect(ui->actionView_Variable_Window, &QAction::triggered, this, &LammpsGui::view_variables);
connect(ui->action_1, &QAction::triggered, this, &LammpsGui::open_recent);
connect(ui->action_2, &QAction::triggered, this, &LammpsGui::open_recent);
@ -307,6 +309,7 @@ LammpsGui::~LammpsGui()
delete chartwindow;
delete dirstatus;
delete varwindow;
delete slideshow;
}
void LammpsGui::new_document()
@ -545,6 +548,10 @@ void LammpsGui::open_file(const QString &fileName)
dirstatus->setText(QString(" Directory: ") + current_dir);
status->setText("Ready.");
if (slideshow) {
delete slideshow;
slideshow = nullptr;
}
update_variables();
}
@ -710,20 +717,25 @@ void LammpsGui::logupdate()
}
}
// get timestep
int step = 0;
void *ptr = lammps.last_thermo("step", 0);
if (ptr) {
if (lammps.extract_setting("bigint") == 4)
step = *(int *)ptr;
else
step = (int)*(int64_t *)ptr;
}
// extract cached thermo data
if (chartwindow) {
// thermo data is not yet valid during setup
void *ptr = lammps.last_thermo("setup", 0);
if (ptr && *(int *)ptr) return;
ptr = lammps.last_thermo("step", 0);
ptr = lammps.last_thermo("num", 0);
if (ptr) {
int step = 0;
if (lammps.extract_setting("bigint") == 4)
step = *(int *)ptr;
else
step = (int)*(int64_t *)ptr;
int ncols = *(int *)lammps.last_thermo("num", 0);
int ncols = *(int *)ptr;
// check if the column assignment has changed
// if yes, delete charts and start over
@ -768,6 +780,22 @@ void LammpsGui::logupdate()
}
}
}
// update list of available image file names
QString imagefile = (const char *)lammps.last_thermo("imagename", 0);
if (!imagefile.isEmpty()) {
if (!slideshow) {
slideshow = new SlideShow(current_file);
if (QSettings().value("viewslide", true).toBool())
slideshow->show();
else
slideshow->hide();
} else {
slideshow->setWindowTitle(QString("LAMMPS-GUI - Slide Show: ") + current_file);
}
slideshow->add_image(imagefile);
}
}
void LammpsGui::modified()
@ -956,6 +984,12 @@ void LammpsGui::do_run(bool use_buffer)
else
chartwindow->hide();
if (slideshow) {
slideshow->setWindowTitle("LAMMPS-GUI - Slide Show");
slideshow->clear();
slideshow->hide();
}
logupdater = new QTimer(this);
connect(logupdater, &QTimer::timeout, this, &LammpsGui::logupdate);
logupdater->start(100);
@ -982,6 +1016,15 @@ void LammpsGui::render_image()
imagewindow->show();
}
void LammpsGui::view_slides()
{
if (!slideshow) slideshow = new SlideShow(current_file);
if (slideshow->isVisible())
slideshow->hide();
else
slideshow->show();
}
void LammpsGui::view_chart()
{
QSettings settings;
@ -1068,6 +1111,7 @@ void LammpsGui::about()
QMessageBox msg;
msg.setWindowTitle("About LAMMPS");
msg.setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
msg.setText(version.c_str());
msg.setInformativeText(info.c_str());
msg.setIconPixmap(QPixmap(":/lammps-icon-128x128.png").scaled(64, 64));
@ -1087,6 +1131,7 @@ void LammpsGui::help()
{
QMessageBox msg;
msg.setWindowTitle("LAMMPS-GUI Quick Help");
msg.setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
msg.setText("<div>This is LAMMPS-GUI version " LAMMPS_GUI_VERSION "</div>");
msg.setInformativeText("<p>LAMMPS GUI is a graphical text editor that is linked to the LAMMPS "
"library and thus can run LAMMPS directly using the contents of the "

View File

@ -45,6 +45,7 @@ class StdCapture;
class Preferences;
class ImageViewer;
class ChartWindow;
class SlideShow;
class LammpsGui : public QMainWindow {
Q_OBJECT
@ -84,6 +85,7 @@ private slots:
void stop_run();
void edit_variables();
void render_image();
void view_slides();
void view_image();
void view_chart();
void view_log();
@ -107,6 +109,7 @@ private:
LogWindow *logwindow;
ImageViewer *imagewindow;
ChartWindow *chartwindow;
SlideShow *slideshow;
QTimer *logupdater;
QLabel *dirstatus;
QProgressBar *progress;

View File

@ -1,49 +1,57 @@
<!-- -*- xml -*- -->
<RCC>
<qresource prefix="/">
<file>lammps-icon-128x128.png</file>
<file>antialias.png</file>
<file>application-calc.png</file>
<file>application-exit.png</file>
<file>application-plot.png</file>
<file>axes-img.png</file>
<file>document-new.png</file>
<file>document-open-recent.png</file>
<file>document-open.png</file>
<file>document-revert.png</file>
<file>document-save-as.png</file>
<file>document-save.png</file>
<file>edit-copy.png</file>
<file>edit-cut.png</file>
<file>edit-delete.png</file>
<file>edit-paste.png</file>
<file>edit-redo.png</file>
<file>edit-undo.png</file>
<file>emblem-photos.png</file>
<file>gtk-go-down.png</file>
<file>gtk-go-up.png</file>
<file>gtk-zoom-fit.png</file>
<file>gtk-zoom-in.png</file>
<file>gtk-zoom-out.png</file>
<file>hd-img.png</file>
<file>help-about.png</file>
<file>help-browser.png</file>
<file>help-faq.png</file>
<file>help_index.table</file>
<file>object-rotate-left.png</file>
<file>object-rotate-right.png</file>
<file>ovito.png</file>
<file>preferences-desktop-font.png</file>
<file>preferences-desktop-personal.png</file>
<file>preferences-desktop.png</file>
<file>process-stop.png</file>
<file>run-file.png</file>
<file>system-box.png</file>
<file>system-help.png</file>
<file>system-run.png</file>
<file>utilities-terminal.png</file>
<file>vdw-style.png</file>
<file>vmd.png</file>
<file>window-close.png</file>
<file>x-office-drawing.png</file>
</qresource>
<qresource prefix="/">
<file>lammps-icon-128x128.png</file>
<file>antialias.png</file>
<file>application-calc.png</file>
<file>application-exit.png</file>
<file>application-plot.png</file>
<file>axes-img.png</file>
<file>document-new.png</file>
<file>document-open-recent.png</file>
<file>document-open.png</file>
<file>document-revert.png</file>
<file>document-save-as.png</file>
<file>document-save.png</file>
<file>edit-copy.png</file>
<file>edit-cut.png</file>
<file>edit-delete.png</file>
<file>edit-paste.png</file>
<file>edit-redo.png</file>
<file>edit-undo.png</file>
<file>emblem-photos.png</file>
<file>go-first.png</file>
<file>go-last.png</file>
<file>go-next-2.png</file>
<file>go-previous-2.png</file>
<file>gtk-go-down.png</file>
<file>gtk-go-up.png</file>
<file>gtk-zoom-fit.png</file>
<file>gtk-zoom-in.png</file>
<file>gtk-zoom-out.png</file>
<file>hd-img.png</file>
<file>help-about.png</file>
<file>help-browser.png</file>
<file>help-faq.png</file>
<file>help_index.table</file>
<file>image-x-generic.png</file>
<file>media-playback-start-2.png</file>
<file>media-playlist-repeat.png</file>
<file>object-rotate-left.png</file>
<file>object-rotate-right.png</file>
<file>ovito.png</file>
<file>preferences-desktop-font.png</file>
<file>preferences-desktop-personal.png</file>
<file>preferences-desktop.png</file>
<file>process-stop.png</file>
<file>run-file.png</file>
<file>system-box.png</file>
<file>system-help.png</file>
<file>system-run.png</file>
<file>utilities-terminal.png</file>
<file>vdw-style.png</file>
<file>vmd.png</file>
<file>window-close.png</file>
<file>x-office-drawing.png</file>
</qresource>
</RCC>

View File

@ -93,6 +93,7 @@
<addaction name="actionView_Log_Window"/>
<addaction name="actionView_Graph_Window"/>
<addaction name="actionView_Image_Window"/>
<addaction name="actionView_Slide_Show"/>
<addaction name="actionView_Variable_Window"/>
</widget>
<addaction name="menuFile"/>
@ -250,7 +251,7 @@
<iconset theme=":/emblem-photos.png"/>
</property>
<property name="text">
<string>View &amp;Image</string>
<string>Create &amp;Image</string>
</property>
<property name="shortcut">
<string>Ctrl+I</string>
@ -352,6 +353,17 @@
<string>Ctrl+Shift+C</string>
</property>
</action>
<action name="actionView_Slide_Show">
<property name="icon">
<iconset theme=":/image-x-generic.png"/>
</property>
<property name="text">
<string>&amp;Slide Show Window</string>
</property>
<property name="shortcut">
<string>Ctrl+L</string>
</property>
</action>
<action name="action_1">
<property name="icon">
<iconset theme=":/document-open-recent.png"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -78,6 +78,7 @@ Preferences::Preferences(LammpsWrapper *_lammps, QWidget *parent) :
layout->addWidget(tabWidget);
layout->addWidget(buttonBox);
setLayout(layout);
setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
setWindowTitle("LAMMPS-GUI - Preferences");
resize(500, 400);
}
@ -161,6 +162,8 @@ void Preferences::accept()
if (box) settings->setValue("viewlog", box->isChecked());
box = tabWidget->findChild<QCheckBox *>("viewchart");
if (box) settings->setValue("viewchart", box->isChecked());
box = tabWidget->findChild<QCheckBox *>("viewslide");
if (box) settings->setValue("viewslide", box->isChecked());
if (need_relaunch) {
QMessageBox msg(QMessageBox::Information, QString("Relaunching LAMMPS-GUI"),
@ -192,6 +195,9 @@ GeneralTab::GeneralTab(QSettings *_settings, LammpsWrapper *_lammps, QWidget *pa
auto *pltv = new QCheckBox("Show chart window by default");
pltv->setObjectName("viewchart");
pltv->setCheckState(settings->value("viewchart", true).toBool() ? Qt::Checked : Qt::Unchecked);
auto *sldv = new QCheckBox("Show slide show window by default");
sldv->setObjectName("viewslide");
sldv->setCheckState(settings->value("viewslide", true).toBool() ? Qt::Checked : Qt::Unchecked);
auto *logr = new QCheckBox("Replace log window on new run");
logr->setObjectName("logreplace");
logr->setCheckState(settings->value("logreplace", false).toBool() ? Qt::Checked
@ -232,6 +238,7 @@ GeneralTab::GeneralTab(QSettings *_settings, LammpsWrapper *_lammps, QWidget *pa
layout->addWidget(cite);
layout->addWidget(logv);
layout->addWidget(pltv);
layout->addWidget(sldv);
layout->addWidget(logr);
layout->addWidget(pltr);
layout->addWidget(imgr);

View File

@ -55,6 +55,7 @@ SetVariables::SetVariables(QList<QPair<QString, QString>> &_vars, QWidget *paren
layout->addWidget(buttonBox);
setLayout(layout);
setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
setWindowTitle("LAMMPS-GUI - Set Variables");
resize(300, 200);
}

View File

@ -0,0 +1,280 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "slideshow.h"
#include <QDialogButtonBox>
#include <QFileInfo>
#include <QGuiApplication>
#include <QHBoxLayout>
#include <QImage>
#include <QImageReader>
#include <QLabel>
#include <QPalette>
#include <QPushButton>
#include <QScreen>
#include <QSettings>
#include <QShortcut>
#include <QSpacerItem>
#include <QTimer>
#include <QVBoxLayout>
SlideShow::SlideShow(const QString &fileName, QWidget *parent) :
QDialog(parent), playtimer(nullptr), imageLabel(new QLabel), imageName(new QLabel("(none)")),
do_loop(true)
{
imageLabel->setBackgroundRole(QPalette::Base);
imageLabel->setScaledContents(false);
imageLabel->setMinimumSize(100, 100);
imageName->setFrameStyle(QFrame::Raised);
imageName->setFrameShape(QFrame::Panel);
imageName->setAlignment(Qt::AlignCenter);
imageName->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
auto *shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this);
QObject::connect(shortcut, &QShortcut::activated, this, &SlideShow::close);
buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
auto *mainLayout = new QVBoxLayout;
auto *navLayout = new QHBoxLayout;
auto *botLayout = new QHBoxLayout;
// workaround for incorrect highlight bug on macOS
auto *dummy = new QPushButton(QIcon(), "");
dummy->hide();
auto *gofirst = new QPushButton(QIcon(":/go-first.png"), "");
gofirst->setToolTip("Go to first Image");
auto *goprev = new QPushButton(QIcon(":/go-previous-2.png"), "");
goprev->setToolTip("Go to previous Image");
auto *goplay = new QPushButton(QIcon(":/media-playback-start-2.png"), "");
goplay->setToolTip("Play animation");
goplay->setCheckable(true);
goplay->setChecked(playtimer);
goplay->setObjectName("play");
auto *gonext = new QPushButton(QIcon(":/go-next-2.png"), "");
gonext->setToolTip("Go to next Image");
auto *golast = new QPushButton(QIcon(":/go-last.png"), "");
golast->setToolTip("Go to last Image");
auto *goloop = new QPushButton(QIcon(":/media-playlist-repeat.png"), "");
goloop->setToolTip("Loop animation");
goloop->setCheckable(true);
goloop->setChecked(do_loop);
auto *zoomin = new QPushButton(QIcon(":/gtk-zoom-in.png"), "");
zoomin->setToolTip("Zoom in by 10 percent");
auto *zoomout = new QPushButton(QIcon(":/gtk-zoom-out.png"), "");
zoomout->setToolTip("Zoom out by 10 percent");
auto *normal = new QPushButton(QIcon(":/gtk-zoom-fit.png"), "");
normal->setToolTip("Reset zoom to normal");
connect(gofirst, &QPushButton::released, this, &SlideShow::first);
connect(goprev, &QPushButton::released, this, &SlideShow::prev);
connect(goplay, &QPushButton::released, this, &SlideShow::play);
connect(gonext, &QPushButton::released, this, &SlideShow::next);
connect(golast, &QPushButton::released, this, &SlideShow::last);
connect(goloop, &QPushButton::released, this, &SlideShow::loop);
connect(zoomin, &QPushButton::released, this, &SlideShow::zoomIn);
connect(zoomout, &QPushButton::released, this, &SlideShow::zoomOut);
connect(gofirst, &QPushButton::released, this, &SlideShow::first);
connect(normal, &QPushButton::released, this, &SlideShow::normalSize);
navLayout->addSpacerItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum));
navLayout->addWidget(dummy);
navLayout->addWidget(gofirst);
navLayout->addWidget(goprev);
navLayout->addWidget(goplay);
navLayout->addWidget(gonext);
navLayout->addWidget(golast);
navLayout->addWidget(goloop);
navLayout->addWidget(zoomin);
navLayout->addWidget(zoomout);
navLayout->addWidget(normal);
mainLayout->addWidget(imageLabel);
mainLayout->addLayout(navLayout);
botLayout->addWidget(imageName);
botLayout->addWidget(buttonBox);
botLayout->setStretch(0, 3);
mainLayout->addLayout(botLayout);
setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
setWindowTitle(QString("LAMMPS-GUI - Slide Show: ") + QFileInfo(fileName).fileName());
imagefiles.clear();
scaleFactor = 1.0;
current = 0;
auto maxsize = QGuiApplication::primaryScreen()->availableSize() * 4 / 5;
maxheight = maxsize.height();
maxwidth = maxsize.width();
setLayout(mainLayout);
}
void SlideShow::add_image(const QString &filename)
{
if (!imagefiles.contains(filename)) {
int lastidx = imagefiles.size();
imagefiles.append(filename);
loadImage(lastidx);
}
}
void SlideShow::clear()
{
imagefiles.clear();
image.fill(Qt::black);
imageLabel->setPixmap(QPixmap::fromImage(image));
imageLabel->adjustSize();
imageName->setText("(none)");
repaint();
}
void SlideShow::loadImage(int idx)
{
if ((idx < 0) || (idx >= imagefiles.size())) return;
do {
QImageReader reader(imagefiles[idx]);
reader.setAutoTransform(true);
const QImage newImage = reader.read();
// There was an error reading the image file. Try reading the previous image instead.
if (newImage.isNull()) {
--idx;
} else {
int newheight = (int)newImage.height() * scaleFactor;
int newwidth = (int)newImage.width() * scaleFactor;
image = newImage.scaled(newwidth, newheight, Qt::IgnoreAspectRatio,
Qt::SmoothTransformation);
imageLabel->setPixmap(QPixmap::fromImage(image));
imageLabel->setMinimumSize(newwidth, newheight);
imageName->setText(QString(" Image %1 / %2 : %3 ")
.arg(idx + 1)
.arg(imagefiles.size())
.arg(imagefiles[idx]));
adjustSize();
current = idx;
break;
}
} while (idx >= 0);
}
void SlideShow::first()
{
current = 0;
loadImage(current);
}
void SlideShow::last()
{
current = imagefiles.size() - 1;
loadImage(current);
}
void SlideShow::play()
{
// if we do not loop, start animation from beginning
if (!do_loop) current = 0;
if (playtimer) {
playtimer->stop();
delete playtimer;
playtimer = nullptr;
} else {
playtimer = new QTimer(this);
connect(playtimer, &QTimer::timeout, this, &SlideShow::next);
playtimer->start(100);
}
// reset push button state. use findChild() if not triggered from button.
QPushButton *button = qobject_cast<QPushButton *>(sender());
if (!button) button = findChild<QPushButton *>("play");
if (button) button->setChecked(playtimer);
}
void SlideShow::next()
{
++current;
if (current >= imagefiles.size()) {
if (do_loop) {
current = 0;
} else {
// stop animation
if (playtimer) play();
--current;
}
}
loadImage(current);
}
void SlideShow::prev()
{
--current;
if (current < 0) {
if (do_loop)
current = imagefiles.size() - 1;
else
current = 0;
}
loadImage(current);
}
void SlideShow::loop()
{
QPushButton *button = qobject_cast<QPushButton *>(sender());
do_loop = !do_loop;
button->setChecked(do_loop);
}
void SlideShow::zoomIn()
{
scaleImage(1.1);
}
void SlideShow::zoomOut()
{
scaleImage(0.9);
}
void SlideShow::normalSize()
{
scaleFactor = 1.0;
scaleImage(1.0);
}
void SlideShow::scaleImage(double factor)
{
// compute maxfactor so the image is not scaled beyond 80 of width or height of screen
double maxfactor = 10.0;
maxfactor = qMin((double)maxheight / (double)image.height(), maxfactor);
maxfactor = qMin((double)maxwidth / (double)image.width(), maxfactor);
if (factor > maxfactor) factor = maxfactor;
scaleFactor *= factor;
if (scaleFactor < 0.25) scaleFactor = 0.25;
loadImage(current);
}
// Local Variables:
// c-basic-offset: 4
// End:

View File

@ -0,0 +1,65 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef SLIDESHOW_H
#define SLIDESHOW_H
#include <QDialog>
#include <QImage>
#include <QString>
#include <QStringList>
class QDialogButtonBox;
class QLabel;
class QTimer;
class SlideShow : public QDialog {
Q_OBJECT
public:
explicit SlideShow(const QString &fileName, QWidget *parent = nullptr);
void add_image(const QString &filename);
void clear();
private slots:
void first();
void last();
void next();
void prev();
void play();
void loop();
void zoomIn();
void zoomOut();
void normalSize();
private:
void scaleImage(double factor);
void loadImage(int idx);
private:
QImage image;
QTimer *playtimer;
QLabel *imageLabel, *imageName;
QDialogButtonBox *buttonBox;
double scaleFactor = 1.0;
int current;
int maxwidth, maxheight;
bool do_loop;
QStringList imagefiles;
};
#endif
// Local Variables:
// c-basic-offset: 4
// End:

View File

@ -533,7 +533,7 @@ TEST_F(AtomStyleTest, atomic)
ASSERT_NE(lmp->atom->mass_setflag, nullptr);
ASSERT_NE(lmp->atom->sametag, nullptr);
ASSERT_EQ(lmp->atom->map_style, Atom::MAP_HASH);
ASSERT_EQ(lmp->atom->map_user, 2);
ASSERT_EQ(lmp->atom->map_user, Atom::MAP_HASH);
ASSERT_EQ(lmp->atom->map_tag_max, 4);
BEGIN_HIDE_OUTPUT();
command("pair_coeff * *");
@ -587,7 +587,7 @@ TEST_F(AtomStyleTest, atomic)
ASSERT_EQ(lmp->atom->mass_setflag[1], 1);
ASSERT_EQ(lmp->atom->mass_setflag[2], 1);
ASSERT_EQ(lmp->atom->map_style, Atom::MAP_ARRAY);
ASSERT_EQ(lmp->atom->map_user, 1);
ASSERT_EQ(lmp->atom->map_user, Atom::MAP_ARRAY);
ASSERT_EQ(lmp->atom->map_tag_max, 4);
ASSERT_EQ(lmp->atom->tag_consecutive(), 1);
@ -597,6 +597,7 @@ TEST_F(AtomStyleTest, atomic)
command("delete_atoms group two compress no");
command("write_restart test_atom_styles.restart");
command("clear");
command("atom_modify map hash");
command("read_restart test_atom_styles.restart");
END_HIDE_OUTPUT();
ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic"));
@ -629,8 +630,8 @@ TEST_F(AtomStyleTest, atomic)
EXPECT_NEAR(lmp->atom->mass[2], 2.4, EPSILON);
ASSERT_EQ(lmp->atom->mass_setflag[1], 1);
ASSERT_EQ(lmp->atom->mass_setflag[2], 1);
ASSERT_EQ(lmp->atom->map_style, Atom::MAP_ARRAY);
ASSERT_EQ(lmp->atom->map_user, 1);
ASSERT_EQ(lmp->atom->map_style, Atom::MAP_HASH);
ASSERT_EQ(lmp->atom->map_user, Atom::MAP_HASH);
ASSERT_EQ(lmp->atom->map_tag_max, 3);
BEGIN_HIDE_OUTPUT();
command("reset_atom_ids");
@ -4561,8 +4562,8 @@ TEST_F(AtomStyleTest, property_atom)
expected.atom_style = "atomic";
expected.molecular = Atom::ATOMIC;
expected.tag_enable = 1;
expected.map_style = 1;
expected.map_user = 1;
expected.map_style = Atom::MAP_ARRAY;
expected.map_user = Atom::MAP_ARRAY;
expected.has_type = true;
expected.has_image = true;
expected.has_mask = true;
@ -4663,7 +4664,7 @@ TEST_F(AtomStyleTest, property_atom)
ASSERT_NE(lmp->atom->sametag, nullptr);
ASSERT_EQ(lmp->atom->tag_consecutive(), 1);
ASSERT_EQ(lmp->atom->map_style, Atom::MAP_ARRAY);
ASSERT_EQ(lmp->atom->map_user, 1);
ASSERT_EQ(lmp->atom->map_user, Atom::MAP_ARRAY);
ASSERT_EQ(lmp->atom->map_tag_max, 4);
auto x = lmp->atom->x;
@ -4751,6 +4752,7 @@ TEST_F(AtomStyleTest, property_atom)
expected.has_ianame = true;
expected.has_daname = true;
expected.nextra_store = 12;
expected.map_user = Atom::MAP_NONE;
ASSERT_ATOM_STATE_EQ(lmp->atom, expected);
ASSERT_NE(lmp->atom->avec, nullptr);