diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 623872c6..ac86e4ab 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,7 +1,7 @@ { "name": "Atomify Dev Container with Emscripten", "image": "mcr.microsoft.com/devcontainers/base:ubuntu", - + "features": { "ghcr.io/devcontainers/features/node:1": { "version": "lts" @@ -18,10 +18,7 @@ "customizations": { "vscode": { - "extensions": [ - "ms-vscode.cpptools", - "ms-python.python" - ], + "extensions": ["ms-vscode.cpptools", "ms-python.python"], "settings": { "terminal.integrated.defaultProfile.linux": "bash" } @@ -30,4 +27,3 @@ "remoteUser": "vscode" } - diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 47000ea3..9426e18c 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -32,8 +32,8 @@ jobs: run: npm run typecheck - name: Run Tests run: npm run test:run - - name: Run Prettier - run: npx prettier . + - name: Run Lint + run: npm run lint - name: Build app run: npm run predeploy - name: Upload artifact diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..254b5297 --- /dev/null +++ b/biome.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.3.8/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": true, + "includes": [ + "**", + "!**/node_modules", + "!**/dist", + "!**/build", + "!**/cpp", + "!**/public/jupyter", + "!**/public/lammps.mjs", + "!**/public/lammps.wasm", + "!**/src/wasm" + ] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 100 + }, + "assist": { "actions": { "source": { "organizeImports": "on" } } }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "correctness": { + "noUnusedVariables": "error", + "useJsxKeyInIterable": "warn" + }, + "suspicious": { + "noExplicitAny": "warn", + "noArrayIndexKey": "warn", + "useIterableCallbackReturn": "warn", + "noAssignInExpressions": "warn" + }, + "complexity": { + "noBannedTypes": "warn", + "noImportantStyles": "off" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double", + "jsxQuoteStyle": "double", + "trailingCommas": "es5", + "semicolons": "always" + } + } +} diff --git a/jupyter-lite.json b/jupyter-lite.json index a180a2eb..8ae833b6 100644 --- a/jupyter-lite.json +++ b/jupyter-lite.json @@ -5,4 +5,4 @@ "settingsStorageName": "JupyterLite Storage", "workspacesStorageName": "JupyterLite Storage" } -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index c801b6b4..57592d28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "easy-peasy": "^6.0.5", "katex": "^0.16.0", "localforage": "^1.10.0", - "mixpanel-browser": "^2.45.0", + "mixpanel-browser": "^2.72.0", "monaco-editor": "^0.55.1", "omovi": "^0.21.0", "protobufjs": "^7.5.4", @@ -45,10 +45,10 @@ "web-vitals": "^5.1.0" }, "devDependencies": { + "@biomejs/biome": "^2.3.8", "@jupyterlab/nbformat": "^4.5.0", "@testing-library/jest-dom": "^6.9.1", "@types/emscripten": "^1.41.5", - "@types/mixpanel-browser": "^2.38.0", "@types/node": "^20.19.25", "@types/styled-components": "^5.1.26", "@types/uuid": "^8.3.4", @@ -528,6 +528,169 @@ "node": ">=6.9.0" } }, + "node_modules/@biomejs/biome": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.8.tgz", + "integrity": "sha512-Qjsgoe6FEBxWAUzwFGFrB+1+M8y/y5kwmg5CHac+GSVOdmOIqsAiXM5QMVGZJ1eCUCLlPZtq4aFAQ0eawEUuUA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.3.8", + "@biomejs/cli-darwin-x64": "2.3.8", + "@biomejs/cli-linux-arm64": "2.3.8", + "@biomejs/cli-linux-arm64-musl": "2.3.8", + "@biomejs/cli-linux-x64": "2.3.8", + "@biomejs/cli-linux-x64-musl": "2.3.8", + "@biomejs/cli-win32-arm64": "2.3.8", + "@biomejs/cli-win32-x64": "2.3.8" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.8.tgz", + "integrity": "sha512-HM4Zg9CGQ3txTPflxD19n8MFPrmUAjaC7PQdLkugeeC0cQ+PiVrd7i09gaBS/11QKsTDBJhVg85CEIK9f50Qww==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.8.tgz", + "integrity": "sha512-lUDQ03D7y/qEao7RgdjWVGCu+BLYadhKTm40HkpJIi6kn8LSv5PAwRlew/DmwP4YZ9ke9XXoTIQDO1vAnbRZlA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.8.tgz", + "integrity": "sha512-Uo1OJnIkJgSgF+USx970fsM/drtPcQ39I+JO+Fjsaa9ZdCN1oysQmy6oAGbyESlouz+rzEckLTF6DS7cWse95g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.8.tgz", + "integrity": "sha512-PShR4mM0sjksUMyxbyPNMxoKFPVF48fU8Qe8Sfx6w6F42verbwRLbz+QiKNiDPRJwUoMG1nPM50OBL3aOnTevA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.8.tgz", + "integrity": "sha512-QDPMD5bQz6qOVb3kiBui0zKZXASLo0NIQ9JVJio5RveBEFgDgsvJFUvZIbMbUZT3T00M/1wdzwWXk4GIh0KaAw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.8.tgz", + "integrity": "sha512-YGLkqU91r1276uwSjiUD/xaVikdxgV1QpsicT0bIA1TaieM6E5ibMZeSyjQ/izBn4tKQthUSsVZacmoJfa3pDA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.8.tgz", + "integrity": "sha512-H4IoCHvL1fXKDrTALeTKMiE7GGWFAraDwBYFquE/L/5r1927Te0mYIGseXi4F+lrrwhSWbSGt5qPFswNoBaCxg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.8.tgz", + "integrity": "sha512-RguzimPoZWtBapfKhKjcWXBVI91tiSprqdBYu7tWhgN8pKRZhw24rFeNZTNf6UiBfjCYCi9eFQs/JzJZIhuK4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, "node_modules/@csstools/color-helpers": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", @@ -2254,13 +2417,6 @@ "@types/unist": "*" } }, - "node_modules/@types/mixpanel-browser": { - "version": "2.60.0", - "resolved": "https://registry.npmjs.org/@types/mixpanel-browser/-/mixpanel-browser-2.60.0.tgz", - "integrity": "sha512-70oe8T3KdxHwsSo5aZphALdoqcsIorQBrlisnouIn9Do4dmC2C6/D56978CmSE/BO2QHgb85ojPGa4R8OFvVHA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", diff --git a/package.json b/package.json index 4f660bc6..2312db0d 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,8 @@ "test:run": "vitest run", "test:ui": "vitest --ui", "typecheck": "tsc --noEmit", + "lint": "biome check .", + "lint:fix": "biome check --write .", "predeploy": "npm run build", "deploy": "gh-pages -d dist" }, @@ -64,6 +66,7 @@ ] }, "devDependencies": { + "@biomejs/biome": "^2.3.8", "@jupyterlab/nbformat": "^4.5.0", "@testing-library/jest-dom": "^6.9.1", "@types/emscripten": "^1.41.5", diff --git a/public/examples/examples.json b/public/examples/examples.json index 1c320140..574c631f 100644 --- a/public/examples/examples.json +++ b/public/examples/examples.json @@ -1,1375 +1,1196 @@ { - "baseUrl": "examples", - "title": "Examples", - "descriptionFile": "examples.md", - "examples": [ - { - "id": "diffusion", - "title": "Diffusion", - "description": "This example shows how you can measure the diffusion coefficient using the mean square displacement. The white atoms have mass 1 while the red atoms have mass 4. This results in the red atoms having diffusion coefficient half the value of the white ones.", - "analysisDescription": "# About this simulation\nWe simulate two Lennard Jones particle types with masses 1.0 and 4.0. The diffusion coefficient [https://en.wikipedia.org/wiki/Mass_diffusivity](scales like) D$\\propto 1/\\sqrt{m}$, so we should see a factor 2 higher diffusion coefficient for the small molecules.", - "imageUrl": "diffusion/diffusion/simple_diffusion.png", - "inputScript": "simple_diffusion.in", - "keywords": [ - "lennard jones", - "diffusion" - ], - "files": [ - { - "fileName": "simple_diffusion.in", - "url": "diffusion/diffusion/simple_diffusion.in" - } - ] - }, - { - "id": "2d-msd-diffusion", - "title": "2D diffusion coefficient MSD", - "description": "We measure the diffusion coefficient using the mean square displacement.", - "analysisDescription": "# About this simulation\nWe measure the diffusion coefficient using the mean square displacement.", - "analysisScript": "2d-msd-diffusion.ipynb", - "imageUrl": "diffusion/2d-msd-diffusion/2d-msd-diffusion.png", - "inputScript": "2d-msd-diffusion.in", - "keywords": [ - "lennard jones", - "diffusion", - "mean square displacement" - ], - "files": [ - { - "fileName": "2d-msd-diffusion.in", - "url": "diffusion/2d-msd-diffusion/2d-msd-diffusion.in" - }, - { - "fileName": "2d-msd-diffusion.ipynb", - "url": "diffusion/2d-msd-diffusion/2d-msd-diffusion.ipynb" - } - ] - }, - { - "id": "2d-vacf-diffusion", - "title": "2D diffusion coefficient VACF", - "description": "We measure the diffusion coefficient using the velocity auto correlation function.", - "analysisDescription": "# About this simulation\nWe measure the diffusion coefficient using the velocity auto correlation function.", - "analysisScript": "2d-vacf-diffusion.ipynb", - "imageUrl": "diffusion/2d-vacf-diffusion/2d-vacf-diffusion.png", - "inputScript": "2d-vacf-diffusion.in", - "keywords": [ - "lennard jones", - "diffusion", - "velocity autocorrelation function" - ], - "files": [ - { - "fileName": "2d-vacf-diffusion.in", - "url": "diffusion/2d-vacf-diffusion/2d-vacf-diffusion.in" - }, - { - "fileName": "2d-vacf-diffusion.ipynb", - "url": "diffusion/2d-vacf-diffusion/2d-vacf-diffusion.ipynb" - } - ] - }, - { - "id": "proteinfolding", - "title": "Protein folding", - "description": "During this short simulation the protein evolves from an unfolded initial conformation to a misfolded conformation. It can take a very long time.", - "imageUrl": "moltemplate/frustrated/frustrated.png", - "inputScript": "run_short_sim.in.nvt", - "keywords": [ - "protein folding", - "moltemplate" - ], - "files": [ - { - "fileName": "table_dihedral_frustrated.dat", - "url": "moltemplate/frustrated/table_dihedral_frustrated.dat" - }, - { - "fileName": "system.in.init", - "url": "moltemplate/frustrated/system.in.init" - }, - { - "fileName": "system.in.settings", - "url": "moltemplate/frustrated/system.in.settings" - }, - { - "fileName": "system.data", - "url": "moltemplate/frustrated/system.data" - }, - { - "fileName": "run_short_sim.in.nvt", - "url": "moltemplate/frustrated/run_short_sim.in.nvt" - } - ] - }, - { - "id": "2D-lj-fluid", - "title": "2D Lennard Jones fluid", - "description": "This simulation consists a binary 2D gas of LJ particles.", - "imageUrl": "simongravelle/liquids/2D-lj-fluid/2D-lj-fluid.png", - "inputScript": "2D-lj-fluid.in", - "keywords": [ - "lennard jones", - "fluid", - "2d" - ], - "author": "Simon Gravelle", - "authorUrl": "https://simongravelle.github.io/", - "files": [ - { - "fileName": "2D-lj-fluid.in", - "url": "simongravelle/liquids/2D-lj-fluid/2D-lj-fluid.in" - } - ] - }, - { - "id": "3D-lj-fluid", - "title": "3D Lennard Jones fluid", - "description": "This simulation consists a binary 3D gas of LJ particles.", - "imageUrl": "simongravelle/liquids/3D-lj-fluid/3D-lj-fluid.png", - "inputScript": "3D-lj-fluid.in", - "keywords": [ - "lennard jones", - "fluid" - ], - "author": "Simon Gravelle", - "authorUrl": "https://simongravelle.github.io/", - "files": [ - { - "fileName": "3D-lj-fluid.in", - "url": "simongravelle/liquids/3D-lj-fluid/3D-lj-fluid.in" - } - ] - }, - { - "id": "nanoporous_sio2", - "title": "Large nanoporous SiO2", - "description": "A nanoporous (porosity 0.75) silica glass with 1.5 million atoms. ", - "imageUrl": "silica/nanoporous_sio2/nanoporous_sio2.png", - "inputScript": "nanoporous_sio2.in", - "keywords": [ - "vashishta", - "sio2", - "nanoporous_sio2" - ], - "files": [ - { - "fileName": "nanoporous_sio2.in", - "url": "silica/nanoporous_sio2/nanoporous_sio2.in" - }, - { - "fileName": "nanoporous_sio2.data", - "url": "silica/nanoporous_sio2/nanoporous_sio2.data" - }, - { - "fileName": "SiO2.vashishta", - "url": "silica/nanoporous_sio2/SiO2.vashishta" - } - ] - }, - { - "id": "generate_nanoporous", - "title": "Generate nanoporous silica", - "description": "Generate a nanoporous silica structure from betacristobalite using the vashishta potential.", - "imageUrl": "silica/generate_nanoporous/generate_nanoporous.png", - "inputScript": "generate_nanoporous.in", - "keywords": [ - "vashishta", - "sio2", - "amorphous", - "nanoporous" - ], - "files": [ - { - "fileName": "SiO2.vashishta", - "url": "silica/generate_nanoporous/SiO2.vashishta" - }, - { - "fileName": "generate_nanoporous.in", - "url": "silica/generate_nanoporous/generate_nanoporous.in" - }, - { - "fileName": "betacristobalite.data", - "url": "silica/generate_nanoporous/betacristobalite.data" - } - ] - }, - { - "id": "reax_cho", - "title": "Hydrocarbon oxcidation", - "description": "Hydrocarbons (such as pentane) will at high temperatures react with oxygen and form water, CO, CO2, HO2 and OH. After around 3000 timesteps, we see some interesting reactions forming new molecules.", - "imageUrl": "reaxff/CHO/CHO.png", - "inputScript": "CHO.in", - "keywords": [ - "reaxff", - "hydrocarbon", - "pentane", - "water" - ], - "files": [ - { - "fileName": "lmp_control", - "url": "reaxff/CHO/lmp_control" - }, - { - "fileName": "CHO.in", - "url": "reaxff/CHO/CHO.in" - }, - { - "fileName": "ffield.reax.cho", - "url": "reaxff/CHO/ffield.reax.cho" - }, - { - "fileName": "data.CHO", - "url": "reaxff/CHO/data.CHO" - }, - { - "fileName": "param.qeq", - "url": "reaxff/CHO/param.qeq" - } - ] - }, - { - "id": "sic_nanoparticle", - "title": "SiC nanoparticle", - "description": "A silicon carbide (SiC) nano particle in a carbon gas. The whole system is neutral, but initially, the particle has net charge. In this simulation, you can observe how the carbon gas attaches to the surface. The system cools down from 2200 K to 500 K.", - "imageUrl": "sic/nanoparticle/nanoparticle.png", - "inputScript": "nanoparticle.in", - "keywords": [ - "vashishta", - "sic", - "nanoparticle" - ], - "files": [ - { - "fileName": "nanoparticle.in", - "url": "sic/nanoparticle/nanoparticle.in" - }, - { - "fileName": "make_stoichiometric.in", - "url": "sic/nanoparticle/make_stoichiometric.in" - }, - { - "fileName": "SiC.vashishta", - "url": "sic/nanoparticle/SiC.vashishta" - }, - { - "fileName": "siliconcarbide.data", - "url": "sic/nanoparticle/siliconcarbide.data" - } - ] - }, - { - "id": "sic_faceted_nanoparticle", - "title": "Faceted SiC nanoparticle", - "description": "A faceted SiC nano particle. All facets are of the same type (110 planes), but due a nucleation barrier during a volume conserving shape change (see Mullins, Rohrer 2000) two of the surfaces are prevented from reaching equilibrium.", - "imageUrl": "sic/faceted_nanoparticle/faceted_nanoparticle.png", - "inputScript": "faceted_nanoparticle.in", - "keywords": [ - "vashishta", - "sic", - "nanoparticle" - ], - "files": [ - { - "fileName": "faceted_nanoparticle.in", - "url": "sic/faceted_nanoparticle/faceted_nanoparticle.in" - }, - { - "fileName": "SiC.vashishta", - "url": "sic/faceted_nanoparticle/SiC.vashishta" - }, - { - "fileName": "sic_nanoparticle.data", - "url": "sic/faceted_nanoparticle/sic_nanoparticle.data" - } - ] - }, - { - "id": "singlewater", - "title": "Single water molecule", - "description": "A single water molecule using the vashishta potential.", - "imageUrl": "water/singlewater/singlewater.png", - "inputScript": "singlewater.in", - "keywords": [ - "vashishta", - "water" - ], - "files": [ - { - "fileName": "singlewater.data", - "url": "water/singlewater/singlewater.data" - }, - { - "fileName": "singlewater.in", - "url": "water/singlewater/singlewater.in" - }, - { - "fileName": "H2O.vashishta", - "url": "water/singlewater/H2O.vashishta" - } - ] - }, - { - "id": "watervapor", - "title": "Water vapor", - "description": "Low density water gas using the vashishta potential.", - "imageUrl": "water/vapor/vapor.png", - "inputScript": "vapor.in", - "keywords": [ - "vashishta", - "water" - ], - "files": [ - { - "fileName": "vapor.data", - "url": "water/vapor/vapor.data" - }, - { - "fileName": "vapor.in", - "url": "water/vapor/vapor.in" - }, - { - "fileName": "H2O.vashishta", - "url": "water/vapor/H2O.vashishta" - } - ] - }, - { - "id": "granular_patterns", - "title": "Pattern formation in granular materials", - "description": "When particles (like sand, but really any particle) lie on a vibrating surface, there are various patterns that suddenly appear for certain values for the frequency and amplitude. In this simulation, you will see one such pattern. It might take some time, so be patient.", - "imageUrl": "granular/patterns/patterns.png", - "inputScript": "patterns.in", - "keywords": [ - "granular" - ], - "files": [ - { - "fileName": "patterns.in", - "url": "granular/patterns/patterns.in" - } - ] - }, - { - "id": "go-nanoparticle", - "title": "Graphene Oxcide nanoparticle", - "description": "The simulation consists of a single graphene oxide particle with a few water molecules. The initial GO nanoparticle has been generated using [make graphitics].", - "imageUrl": "simongravelle/solids/GO-nanoparticle/GO-nanoparticle.png", - "inputScript": "GO-nanoparticle.in", - "keywords": [ - "airebo", - "graphene oxcide", - "graphene", - "simongravelle" - ], - "author": "Simon Gravelle", - "authorUrl": "https://simongravelle.github.io/", - "files": [ - { - "fileName": "GO-nanoparticle.in", - "url": "simongravelle/solids/GO-nanoparticle/GO-nanoparticle.in" - }, - { - "fileName": "GO-nanoparticle.data", - "url": "simongravelle/solids/GO-nanoparticle/GO-nanoparticle.data" - }, - { - "fileName": "PARM.lammps", - "url": "simongravelle/solids/GO-nanoparticle/PARM.lammps" - } - ] - }, - { - "id": "cnt_deformation", - "title": "Carbon nanotube under deformation", - "description": "The simulation consists of a single carbon nanotube (CNT) in vacuum. At the beginning of the simulation, a few atoms are removed from the CNT. The CNT is divided into three parts: the central part and the two edges. The two edges are forced to move, which leads to the gradual elongation of the CNT. Eventually, the CNT breaks. The breaking of the chemical bonds is permitted by the use of a reactive force field (AIREBO).", - "imageUrl": "simongravelle/solids/cnt-under-deformation/cnt-under-deformation.png", - "inputScript": "cnt-under-deformation.in", - "keywords": [ - "airebo", - "cnt", - "carbon nanotube", - "carbon", - "simongravelle" - ], - "author": "Simon Gravelle", - "authorUrl": "https://simongravelle.github.io/", - "files": [ - { - "fileName": "cnt-under-deformation.data", - "url": "simongravelle/solids/cnt-under-deformation/cnt-under-deformation.data" - }, - { - "fileName": "cnt-under-deformation.in", - "url": "simongravelle/solids/cnt-under-deformation/cnt-under-deformation.in" - }, - { - "fileName": "CH.airebo", - "url": "simongravelle/solids/shared/CH.airebo" - } - ] - }, - { - "id": "nacl-solution", - "title": "NaCl solution", - "description": "The simulation consists of a bulk solution of NaCl in water.", - "imageUrl": "simongravelle/liquids/nacl-solution/nacl-solution.png", - "inputScript": "nacl-solution.in", - "keywords": [ - "lennard jones", - "salt", - "water", - "tip4p" - ], - "author": "Simon Gravelle", - "authorUrl": "https://simongravelle.github.io/", - "files": [ - { - "fileName": "nacl-solution.in", - "url": "simongravelle/liquids/nacl-solution/nacl-solution.in" - }, - { - "fileName": "nacl-solution.data", - "url": "simongravelle/liquids/nacl-solution/nacl-solution.data" - }, - { - "fileName": "PARM.lammps", - "url": "simongravelle/liquids/nacl-solution/PARM.lammps" - } - ] - }, - { - "id": "reversibly-adsorbing-particles", - "title": "Adsorption combined with diffusion create pink noise in nanopore", - "description": "The simulation consists of particles diffusing inside a cylindrical nanopore. The surface of the nanopore is covered with adsorbing sites, and the particles reversibly adsorb at the inner surface of the nanopore. The adsorption/desorption processes are modelled using bond/create and bond/break commands respectively. A bond forms if a particle comes close enough to a trap. An additional harmonic potential is added to trapped particles. The wall of the cylinder is modelled using the wall/region command.", - "imageUrl": "simongravelle/interfaces/reversibly-adsorbing-particles/reversibly-adsorbing-particles.png", - "inputScript": "reversibly-adsorbing-particles.in", - "keywords": [ - "lennard jones", - "salt", - "water", - "tip4p" - ], - "author": "Simon Gravelle", - "authorUrl": "https://simongravelle.github.io/", - "files": [ - { - "fileName": "reversibly-adsorbing-particles.in", - "url": "simongravelle/interfaces/reversibly-adsorbing-particles/reversibly-adsorbing-particles.in" - }, - { - "fileName": "reversibly-adsorbing-particles.data", - "url": "simongravelle/interfaces/reversibly-adsorbing-particles/reversibly-adsorbing-particles.data" - }, - { - "fileName": "bonds.in", - "url": "simongravelle/interfaces/reversibly-adsorbing-particles/bonds.in" - }, - { - "fileName": "groups.in", - "url": "simongravelle/interfaces/reversibly-adsorbing-particles/groups.in" - } - ] - }, - { - "id": "betacristobalite", - "title": "Silica beta cristobalite", - "description": "Beta cristobalite crystal using the vashishta potential.", - "imageUrl": "silica/betacristobalite/betacristobalite.png", - "inputScript": "betacristobalite.in", - "keywords": [ - "vashishta", - "sio2", - "crystal" - ], - "files": [ - { - "fileName": "betacristobalite.in", - "url": "silica/betacristobalite/betacristobalite.in" - }, - { - "fileName": "SiO2.vashishta", - "url": "silica/betacristobalite/SiO2.vashishta" - }, - { - "fileName": "betacristobalite.data", - "url": "silica/betacristobalite/betacristobalite.data" - } - ] - }, - { - "id": "zeolite_zsm5", - "title": "Zeolite ZSM-5", - "description": "Zeolite ZSM-5 using the vashishta potential.", - "imageUrl": "silica/zeolite_zsm5/zeolite_zsm5.png", - "inputScript": "zeolite_zsm5.in", - "keywords": [ - "vashishta", - "zeolite" - ], - "files": [ - { - "fileName": "zeolite_zsm5.in", - "url": "silica/zeolite_zsm5/zeolite_zsm5.in" - }, - { - "fileName": "zeolite_zsm5.data", - "url": "silica/zeolite_zsm5/zeolite_zsm5.data" - }, - { - "fileName": "SiO2.vashishta", - "url": "silica/zeolite_zsm5/SiO2.vashishta" - } - ] - }, - { - "id": "crack", - "title": "Crack 2D", - "description": "Crack propagation in a 2d solid.", - "imageUrl": "lammps/crack/crack.png", - "inputScript": "crack.in", - "keywords": [ - "lennard jones", - "crack", - "2d" - ], - "files": [ - { - "fileName": "crack.in", - "url": "lammps/crack/crack.in" - } - ] - }, - { - "id": "flow_couette", - "title": "Couette flow 2D", - "description": "Couette flow in a 2d channel.", - "imageUrl": "lammps/flow_couette/flow_couette.png", - "inputScript": "flow_couette.in", - "keywords": [ - "lennard jones", - "flow", - "2d" - ], - "files": [ - { - "fileName": "flow_couette.in", - "url": "lammps/flow_couette/flow_couette.in" - } - ] - }, - { - "id": "flow_poiseuille", - "title": "Poiseuille flow 2D", - "description": "Poiseuille flow in a 2d channel.", - "imageUrl": "lammps/flow_pois/flow_pois.png", - "inputScript": "flow_pois.in", - "keywords": [ - "lennard jones", - "flow", - "2d" - ], - "files": [ - { - "fileName": "flow_pois.in", - "url": "lammps/flow_pois/flow_pois.in" - } - ] - }, - { - "id": "friction", - "title": "Friction 2D", - "description": "Frictional contact of spherical asperities between 2d surfaces.", - "imageUrl": "lammps/friction/friction.png", - "inputScript": "friction.in", - "keywords": [ - "lennard jones", - "friction", - "2d" - ], - "files": [ - { - "fileName": "friction.in", - "url": "lammps/friction/friction.in" - } - ] - }, - { - "id": "cmap", - "title": "CMAP 5-body", - "description": "CMAP 5-body contributions to CHARMM force field.", - "imageUrl": "lammps/cmap/cmap.png", - "inputScript": "in.cmap", - "keywords": [ - "charmm" - ], - "files": [ - { - "fileName": "gagg.data", - "url": "lammps/cmap/gagg.data" - }, - { - "fileName": "in.cmap", - "url": "lammps/cmap/in.cmap" - }, - { - "fileName": "charmm22.cmap", - "url": "lammps/cmap/charmm22.cmap" - } - ] - }, - { - "id": "deposit_atom", - "title": "Deposit atoms", - "description": "Deposition of atoms onto a 3d substrate.", - "imageUrl": "lammps/deposit_atom/deposit.png", - "inputScript": "in.deposit.atom", - "keywords": [ - "lennard jones", - "deposit" - ], - "files": [ - { - "fileName": "in.deposit.atom", - "url": "lammps/deposit_atom/in.deposit.atom" - } - ] - }, - { - "id": "deposit_molecule", - "title": "Deposit molecules", - "description": "Deposition of molecules onto a 3d substrate.", - "imageUrl": "lammps/deposit_molecule/deposit_molecule.png", - "inputScript": "in.deposit.molecule", - "keywords": [ - "lennard jones", - "deposit", - "3d" - ], - "files": [ - { - "fileName": "in.deposit.molecule", - "url": "lammps/deposit_molecule/in.deposit.molecule" - }, - { - "fileName": "molecule.dimer", - "url": "lammps/deposit_molecule/molecule.dimer" - } - ] - }, - { - "id": "micelle", - "title": "Micelle", - "description": "Self-assembly of small lipid-like molecules into 2d bilayers.", - "imageUrl": "lammps/micelle/micelle.png", - "inputScript": "in.micelle", - "keywords": [ - "micelle" - ], - "files": [ - { - "fileName": "data.micelle", - "url": "lammps/micelle/data.micelle" - }, - { - "fileName": "def.micelle", - "url": "lammps/micelle/def.micelle" - }, - { - "fileName": "in.micelle", - "url": "lammps/micelle/in.micelle" - } - ] - }, - { - "id": "obstacle", - "title": "2d obstacle", - "description": "Flow around two voids in a 2d channel.", - "imageUrl": "lammps/obstacle/obstacle.png", - "inputScript": "in.obstacle", - "keywords": [ - "lennard jones", - "flow", - "2d" - ], - "files": [ - { - "fileName": "in.obstacle", - "url": "lammps/obstacle/in.obstacle" - } - ] - }, - { - "id": "peptide", - "title": "Peptide solvation", - "description": "Dynamics of a small solvated peptide chain (5-mer).", - "imageUrl": "lammps/peptide/peptide.png", - "inputScript": "in.peptide", - "keywords": [ - "peptide" - ], - "files": [ - { - "fileName": "in.peptide", - "url": "lammps/peptide/in.peptide" - }, - { - "fileName": "data.peptide", - "url": "lammps/peptide/data.peptide" - } - ] - }, - { - "id": "pour_2d", - "title": "2d pour.", - "description": "Pouring of granular molecules into a 2d box, then chute flow.", - "imageUrl": "lammps/pour_2d/pour_2d.png", - "inputScript": "in.pour.2d", - "keywords": [ - "granular", - "pour", - "2d" - ], - "files": [ - { - "fileName": "in.pour.2d", - "url": "lammps/pour_2d/in.pour.2d" - } - ] - }, - { - "id": "pour_2d_molecule", - "title": "2d molecule pour", - "description": "Pouring of granular molecules into a 2d box, then chute flow.", - "imageUrl": "lammps/pour_2d_molecule/pour_2d_molecule.png", - "inputScript": "in.pour.2d.molecule", - "keywords": [ - "granular", - "pour", - "2d" - ], - "files": [ - { - "fileName": "in.pour.2d.molecule", - "url": "lammps/pour_2d_molecule/in.pour.2d.molecule" - }, - { - "fileName": "molecule.vshape", - "url": "lammps/pour_2d_molecule/molecule.vshape" - } - ] - }, - { - "id": "pour_3d", - "title": "3d pour", - "description": "Pouring of granular particles into a 3d box, then chute flow.", - "imageUrl": "lammps/pour_3d/pour.png", - "inputScript": "in.pour", - "keywords": [ - "granular", - "pour" - ], - "files": [ - { - "fileName": "in.pour", - "url": "lammps/pour_3d/in.pour" - } - ] - }, - { - "id": "shear", - "title": "Shear", - "description": "sideways shear applied to 2d solid.", - "imageUrl": "lammps/shear/shear.png", - "inputScript": "in.shear", - "keywords": [ - "lennard jones", - "shear", - "2d" - ], - "files": [ - { - "fileName": "Ni_u3.eam", - "url": "lammps/shear/Ni_u3.eam" - }, - { - "fileName": "in.shear", - "url": "lammps/shear/in.shear" - } - ] - }, - { - "id": "shear_void", - "title": "Shear with void", - "description": "Sideways shear applied to 2d solid with a void.", - "imageUrl": "lammps/shear_void/shear_void.png", - "inputScript": "in.shear.void", - "keywords": [ - "lennard jones", - "shear", - "2d" - ], - "files": [ - { - "fileName": "in.shear.void", - "url": "lammps/shear_void/in.shear.void" - }, - { - "fileName": "Ni_u3.eam", - "url": "lammps/shear_void/Ni_u3.eam" - } - ] - }, - { - "id": "abstract_translocation", - "title": "Polymer through hole", - "description": "This example contains a (crude and somewhat simple) example of the translocation of a (rather short) polymer through a hole in a wall, surrounded by an explicit LJ solvent.", - "imageUrl": "moltemplate/abstract_translocation/abstract_translocation.png", - "inputScript": "run.in.npt", - "keywords": [ - "polymer" - ], - "files": [ - { - "fileName": "run.in.npt", - "url": "moltemplate/abstract_translocation/run.in.npt" - }, - { - "fileName": "system.in", - "url": "moltemplate/abstract_translocation/system.in" - }, - { - "fileName": "system.in.init", - "url": "moltemplate/abstract_translocation/system.in.init" - }, - { - "fileName": "system.in.settings", - "url": "moltemplate/abstract_translocation/system.in.settings" - }, - { - "fileName": "run.in.nvt", - "url": "moltemplate/abstract_translocation/run.in.nvt" - }, - { - "fileName": "system.data", - "url": "moltemplate/abstract_translocation/system.data" - } - ] - }, - { - "id": "alkane_chain_single", - "title": "Alkane chain", - "description": "This example is a simple simulation of a long alkane chain, in a vacuum at room temperature using the OPLSAA force field.", - "imageUrl": "moltemplate/alkane_chain_single/alkane_chain_2.png", - "inputScript": "run.in.nvt", - "keywords": [ - "alkane" - ], - "files": [ - { - "fileName": "system_after_min.data", - "url": "moltemplate/alkane_chain_single/system_after_min.data" - }, - { - "fileName": "system.in", - "url": "moltemplate/alkane_chain_single/system.in" - }, - { - "fileName": "system.in.init", - "url": "moltemplate/alkane_chain_single/system.in.init" - }, - { - "fileName": "run.in.min", - "url": "moltemplate/alkane_chain_single/run.in.min" - }, - { - "fileName": "system.in.settings", - "url": "moltemplate/alkane_chain_single/system.in.settings" - }, - { - "fileName": "run.in.nvt", - "url": "moltemplate/alkane_chain_single/run.in.nvt" - }, - { - "fileName": "system.data", - "url": "moltemplate/alkane_chain_single/system.data" - }, - { - "fileName": "system.in.charges", - "url": "moltemplate/alkane_chain_single/system.in.charges" - } - ] - }, - { - "id": "benzene", - "title": "Benzene", - "description": "This example shows how to build a box of benzene molecules using the AMBER/GAFF force-field.", - "imageUrl": "moltemplate/benzene/benzene.png", - "inputScript": "run.in.npt", - "keywords": [ - "amber", - "benzene" - ], - "files": [ - { - "fileName": "run.in.npt", - "url": "moltemplate/benzene/run.in.npt" - }, - { - "fileName": "system.in", - "url": "moltemplate/benzene/system.in" - }, - { - "fileName": "system.in.init", - "url": "moltemplate/benzene/system.in.init" - }, - { - "fileName": "system.in.settings", - "url": "moltemplate/benzene/system.in.settings" - }, - { - "fileName": "run.in.nvt", - "url": "moltemplate/benzene/run.in.nvt" - }, - { - "fileName": "system.data", - "url": "moltemplate/benzene/system.data" - } - ] - }, - { - "id": "ice_crystal", - "title": "Ice crystal", - "description": "A simulation of an ice crystal using SPCE water and the shake algorithm.", - "imageUrl": "moltemplate/ice_crystal/ice_crystal.png", - "inputScript": "run.in.npt", - "keywords": [ - "spce", - "water", - "ice", - "shake" - ], - "files": [ - { - "fileName": "run.in.npt", - "url": "moltemplate/ice_crystal/run.in.npt" - }, - { - "fileName": "system.in", - "url": "moltemplate/ice_crystal/system.in" - }, - { - "fileName": "system_after_npt.data", - "url": "moltemplate/ice_crystal/system_after_npt.data" - }, - { - "fileName": "system.in.init", - "url": "moltemplate/ice_crystal/system.in.init" - }, - { - "fileName": "system.in.settings", - "url": "moltemplate/ice_crystal/system.in.settings" - }, - { - "fileName": "run.in.nvt", - "url": "moltemplate/ice_crystal/run.in.nvt" - }, - { - "fileName": "system.data", - "url": "moltemplate/ice_crystal/system.data" - } - ] - }, - { - "id": "methane", - "title": "Methane", - "description": "This example demonstrates how to build a simulation containing a box of methane.", - "imageUrl": "moltemplate/methane/methane.png", - "inputScript": "run.in.npt", - "keywords": [ - "methane" - ], - "files": [ - { - "fileName": "run.in.npt", - "url": "moltemplate/methane/run.in.npt" - }, - { - "fileName": "system_after_min.data", - "url": "moltemplate/methane/system_after_min.data" - }, - { - "fileName": "system.in", - "url": "moltemplate/methane/system.in" - }, - { - "fileName": "system.in.init", - "url": "moltemplate/methane/system.in.init" - }, - { - "fileName": "system.in.settings", - "url": "moltemplate/methane/system.in.settings" - }, - { - "fileName": "run.in.nvt", - "url": "moltemplate/methane/run.in.nvt" - }, - { - "fileName": "system.data", - "url": "moltemplate/methane/system.data" - }, - { - "fileName": "system.in.charges", - "url": "moltemplate/methane/system.in.charges" - } - ] - }, - { - "id": "nanotube_water", - "title": "Water in nanotube", - "description": "This is a small version of a carbon-nanotube, water capillary system.", - "imageUrl": "moltemplate/nanotube+water/nanotube+water.png", - "inputScript": "run.in.npt", - "keywords": [ - "water", - "cnt", - "carbon nanotube" - ], - "files": [ - { - "fileName": "run.in.npt", - "url": "moltemplate/nanotube+water/run.in.npt" - }, - { - "fileName": "system.in", - "url": "moltemplate/nanotube+water/system.in" - }, - { - "fileName": "system.in.init", - "url": "moltemplate/nanotube+water/system.in.init" - }, - { - "fileName": "system.in.settings", - "url": "moltemplate/nanotube+water/system.in.settings" - }, - { - "fileName": "system.data", - "url": "moltemplate/nanotube+water/system.data" - } - ] - }, - { - "id": "water_methane", - "title": "Methane in water", - "description": "This example contains a mixture of SPCE water and methane. The methane molecules use OPLSAA force-field.", - "imageUrl": "moltemplate/waterSPCE+methane/waterSPCE+methane.png", - "inputScript": "run.in.npt", - "keywords": [ - "spce", - "water", - "methane" - ], - "files": [ - { - "fileName": "run.in.npt", - "url": "moltemplate/waterSPCE+methane/run.in.npt" - }, - { - "fileName": "system_after_min.data", - "url": "moltemplate/waterSPCE+methane/system_after_min.data" - }, - { - "fileName": "system.in", - "url": "moltemplate/waterSPCE+methane/system.in" - }, - { - "fileName": "system.in.init", - "url": "moltemplate/waterSPCE+methane/system.in.init" - }, - { - "fileName": "system.in.settings", - "url": "moltemplate/waterSPCE+methane/system.in.settings" - }, - { - "fileName": "run.in.nvt", - "url": "moltemplate/waterSPCE+methane/run.in.nvt" - }, - { - "fileName": "system.data", - "url": "moltemplate/waterSPCE+methane/system.data" - }, - { - "fileName": "system.in.charges", - "url": "moltemplate/waterSPCE+methane/system.in.charges" - } - ] - }, - { - "id": "water_nacl", - "title": "Salt water", - "description": "This example contains a mixture of SPCE water and salt (NaCl).", - "imageUrl": "moltemplate/waterSPCE+Na+Cl/waterSPCE+NA+CL.png", - "inputScript": "run.in.npt", - "keywords": [ - "spce", - "water", - "salt" - ], - "files": [ - { - "fileName": "run.in.npt", - "url": "moltemplate/waterSPCE+Na+Cl/run.in.npt" - }, - { - "fileName": "system.in", - "url": "moltemplate/waterSPCE+Na+Cl/system.in" - }, - { - "fileName": "system.in.init", - "url": "moltemplate/waterSPCE+Na+Cl/system.in.init" - }, - { - "fileName": "system.in.settings", - "url": "moltemplate/waterSPCE+Na+Cl/system.in.settings" - }, - { - "fileName": "run.in.nvt", - "url": "moltemplate/waterSPCE+Na+Cl/run.in.nvt" - }, - { - "fileName": "system.data", - "url": "moltemplate/waterSPCE+Na+Cl/system.data" - } - ] - }, - { - "id": "water_isobutane", - "title": "TIP3P water and isobutane", - "description": "The simulation consists of a mixture of isobutane and water. Over time (less than 1 ns), the two molecules phase-separate.", - "imageUrl": "moltemplate/waterTIP3P+isobutane/waterTIP3P+isobutane.png", - "inputScript": "run.in.npt", - "keywords": [ - "tip3p", - "water", - "isobutane" - ], - "files": [ - { - "fileName": "run.in.npt", - "url": "moltemplate/waterTIP3P+isobutane/run.in.npt" - }, - { - "fileName": "system.in", - "url": "moltemplate/waterTIP3P+isobutane/system.in" - }, - { - "fileName": "system.in.init", - "url": "moltemplate/waterTIP3P+isobutane/system.in.init" - }, - { - "fileName": "system.in.settings", - "url": "moltemplate/waterTIP3P+isobutane/system.in.settings" - }, - { - "fileName": "run.in.nvt", - "url": "moltemplate/waterTIP3P+isobutane/run.in.nvt" - }, - { - "fileName": "system.data", - "url": "moltemplate/waterTIP3P+isobutane/system.data" - } - ] - }, - { - "id": "reax_ab", - "title": "Ammonia-Borine (AB)", - "description": "Combustion of Ammonia-Borine (AB) can be simulated with ReaxFF. Two AB molecules meet and a H2 molecule is formed.", - "imageUrl": "reaxff/AB/AB.png", - "inputScript": "AB.in", - "keywords": [ - "reaxff", - "combustion", - "ammonia borine" - ], - "files": [ - { - "fileName": "lmp_control", - "url": "reaxff/AB/lmp_control" - }, - { - "fileName": "ffield.reax.AB", - "url": "reaxff/AB/ffield.reax.AB" - }, - { - "fileName": "AB.in", - "url": "reaxff/AB/AB.in" - }, - { - "fileName": "data.AB", - "url": "reaxff/AB/data.AB" - }, - { - "fileName": "param.qeq", - "url": "reaxff/AB/param.qeq" - } - ] - }, - { - "id": "reax_feoh3", - "title": "Iron(III) hydroxide", - "description": "In this simulation, we see low density Iron(III) hydroxide (Fe(OH)3) at high temperature.", - "imageUrl": "reaxff/FeOH3/FeOH3.png", - "inputScript": "FeOH3.in", - "keywords": [ - "reaxff", - "iron hydroxide" - ], - "files": [ - { - "fileName": "data.FeOH3", - "url": "reaxff/FeOH3/data.FeOH3" - }, - { - "fileName": "lmp_control", - "url": "reaxff/FeOH3/lmp_control" - }, - { - "fileName": "ffield.reax.Fe_O_C_H", - "url": "reaxff/FeOH3/ffield.reax.Fe_O_C_H" - }, - { - "fileName": "FeOH3.in", - "url": "reaxff/FeOH3/FeOH3.in" - }, - { - "fileName": "param.qeq", - "url": "reaxff/FeOH3/param.qeq" - } - ] - }, - { - "id": "reax_rdf", - "title": "RDX explosive", - "description": "RDX is an organic compound normally used as an explosive, especially in world war II.", - "imageUrl": "reaxff/RDX/RDX.png", - "inputScript": "RDX.in", - "keywords": [ - "reaxff", - "explosive" - ], - "files": [ - { - "fileName": "lmp_control", - "url": "reaxff/RDX/lmp_control" - }, - { - "fileName": "RDX.in", - "url": "reaxff/RDX/RDX.in" - }, - { - "fileName": "data.RDX", - "url": "reaxff/RDX/data.RDX" - }, - { - "fileName": "ffield.reax.rdx", - "url": "reaxff/RDX/ffield.reax.rdx" - }, - { - "fileName": "param.qeq", - "url": "reaxff/RDX/param.qeq" - } - ] - }, - { - "id": "reax_ssz13", - "title": "Zeolite SSZ-13", - "description": "This structure is a zeolite called SSZ-13 (or CHA) and has one of the silicon sites replaced with Aluminum and a hydrogen atom.", - "imageUrl": "reaxff/ssz_13/ssz_13.png", - "inputScript": "ssz_13.in", - "keywords": [ - "reaxff", - "zeolite" - ], - "files": [ - { - "fileName": "ffield_Psofogiannakis_CuOH_2015", - "url": "reaxff/ssz_13/ffield_Psofogiannakis_CuOH_2015" - }, - { - "fileName": "ssz_13.in", - "url": "reaxff/ssz_13/ssz_13.in" - }, - { - "fileName": "CHA_wAl.data", - "url": "reaxff/ssz_13/CHA_wAl.data" - } - ] - }, - { - "id": "reax_voh", - "title": "Vanadium Oxide", - "description": "In this simulation, we see vanadium oxide being simulated using ReaxFF at high temperature.", - "imageUrl": "reaxff/VOH/VOH.png", - "inputScript": "VOH.in", - "keywords": [ - "reaxff", - "vanadium oxide" - ], - "files": [ - { - "fileName": "lmp_control", - "url": "reaxff/VOH/lmp_control" - }, - { - "fileName": "ffield.reax.V_O_C_H", - "url": "reaxff/VOH/ffield.reax.V_O_C_H" - }, - { - "fileName": "data.VOH", - "url": "reaxff/VOH/data.VOH" - }, - { - "fileName": "VOH.in", - "url": "reaxff/VOH/VOH.in" - }, - { - "fileName": "param.qeq", - "url": "reaxff/VOH/param.qeq" - } - ] - }, - { - "id": "reax_znoh2", - "title": "Zn(OH)2", - "description": "In this simulation, we see Zn(OH)2 at high temperature.", - "imageUrl": "reaxff/ZnOH2/ZnOH2.png", - "inputScript": "ZnOH2.in", - "keywords": [ - "reaxff" - ], - "files": [ - { - "fileName": "ZnOH2.in", - "url": "reaxff/ZnOH2/ZnOH2.in" - }, - { - "fileName": "lmp_control", - "url": "reaxff/ZnOH2/lmp_control" - }, - { - "fileName": "data.ZnOH2", - "url": "reaxff/ZnOH2/data.ZnOH2" - }, - { - "fileName": "ffield.reax.ZnOH", - "url": "reaxff/ZnOH2/ffield.reax.ZnOH" - }, - { - "fileName": "param.qeq", - "url": "reaxff/ZnOH2/param.qeq" - } - ] + "baseUrl": "examples", + "title": "Examples", + "descriptionFile": "examples.md", + "examples": [ + { + "id": "diffusion", + "title": "Diffusion", + "description": "This example shows how you can measure the diffusion coefficient using the mean square displacement. The white atoms have mass 1 while the red atoms have mass 4. This results in the red atoms having diffusion coefficient half the value of the white ones.", + "analysisDescription": "# About this simulation\nWe simulate two Lennard Jones particle types with masses 1.0 and 4.0. The diffusion coefficient [https://en.wikipedia.org/wiki/Mass_diffusivity](scales like) D$\\propto 1/\\sqrt{m}$, so we should see a factor 2 higher diffusion coefficient for the small molecules.", + "imageUrl": "diffusion/diffusion/simple_diffusion.png", + "inputScript": "simple_diffusion.in", + "keywords": ["lennard jones", "diffusion"], + "files": [ + { + "fileName": "simple_diffusion.in", + "url": "diffusion/diffusion/simple_diffusion.in" + } + ] + }, + { + "id": "2d-msd-diffusion", + "title": "2D diffusion coefficient MSD", + "description": "We measure the diffusion coefficient using the mean square displacement.", + "analysisDescription": "# About this simulation\nWe measure the diffusion coefficient using the mean square displacement.", + "analysisScript": "2d-msd-diffusion.ipynb", + "imageUrl": "diffusion/2d-msd-diffusion/2d-msd-diffusion.png", + "inputScript": "2d-msd-diffusion.in", + "keywords": ["lennard jones", "diffusion", "mean square displacement"], + "files": [ + { + "fileName": "2d-msd-diffusion.in", + "url": "diffusion/2d-msd-diffusion/2d-msd-diffusion.in" + }, + { + "fileName": "2d-msd-diffusion.ipynb", + "url": "diffusion/2d-msd-diffusion/2d-msd-diffusion.ipynb" + } + ] + }, + { + "id": "2d-vacf-diffusion", + "title": "2D diffusion coefficient VACF", + "description": "We measure the diffusion coefficient using the velocity auto correlation function.", + "analysisDescription": "# About this simulation\nWe measure the diffusion coefficient using the velocity auto correlation function.", + "analysisScript": "2d-vacf-diffusion.ipynb", + "imageUrl": "diffusion/2d-vacf-diffusion/2d-vacf-diffusion.png", + "inputScript": "2d-vacf-diffusion.in", + "keywords": ["lennard jones", "diffusion", "velocity autocorrelation function"], + "files": [ + { + "fileName": "2d-vacf-diffusion.in", + "url": "diffusion/2d-vacf-diffusion/2d-vacf-diffusion.in" + }, + { + "fileName": "2d-vacf-diffusion.ipynb", + "url": "diffusion/2d-vacf-diffusion/2d-vacf-diffusion.ipynb" + } + ] + }, + { + "id": "proteinfolding", + "title": "Protein folding", + "description": "During this short simulation the protein evolves from an unfolded initial conformation to a misfolded conformation. It can take a very long time.", + "imageUrl": "moltemplate/frustrated/frustrated.png", + "inputScript": "run_short_sim.in.nvt", + "keywords": ["protein folding", "moltemplate"], + "files": [ + { + "fileName": "table_dihedral_frustrated.dat", + "url": "moltemplate/frustrated/table_dihedral_frustrated.dat" + }, + { + "fileName": "system.in.init", + "url": "moltemplate/frustrated/system.in.init" + }, + { + "fileName": "system.in.settings", + "url": "moltemplate/frustrated/system.in.settings" + }, + { + "fileName": "system.data", + "url": "moltemplate/frustrated/system.data" + }, + { + "fileName": "run_short_sim.in.nvt", + "url": "moltemplate/frustrated/run_short_sim.in.nvt" + } + ] + }, + { + "id": "2D-lj-fluid", + "title": "2D Lennard Jones fluid", + "description": "This simulation consists a binary 2D gas of LJ particles.", + "imageUrl": "simongravelle/liquids/2D-lj-fluid/2D-lj-fluid.png", + "inputScript": "2D-lj-fluid.in", + "keywords": ["lennard jones", "fluid", "2d"], + "author": "Simon Gravelle", + "authorUrl": "https://simongravelle.github.io/", + "files": [ + { + "fileName": "2D-lj-fluid.in", + "url": "simongravelle/liquids/2D-lj-fluid/2D-lj-fluid.in" + } + ] + }, + { + "id": "3D-lj-fluid", + "title": "3D Lennard Jones fluid", + "description": "This simulation consists a binary 3D gas of LJ particles.", + "imageUrl": "simongravelle/liquids/3D-lj-fluid/3D-lj-fluid.png", + "inputScript": "3D-lj-fluid.in", + "keywords": ["lennard jones", "fluid"], + "author": "Simon Gravelle", + "authorUrl": "https://simongravelle.github.io/", + "files": [ + { + "fileName": "3D-lj-fluid.in", + "url": "simongravelle/liquids/3D-lj-fluid/3D-lj-fluid.in" + } + ] + }, + { + "id": "nanoporous_sio2", + "title": "Large nanoporous SiO2", + "description": "A nanoporous (porosity 0.75) silica glass with 1.5 million atoms. ", + "imageUrl": "silica/nanoporous_sio2/nanoporous_sio2.png", + "inputScript": "nanoporous_sio2.in", + "keywords": ["vashishta", "sio2", "nanoporous_sio2"], + "files": [ + { + "fileName": "nanoporous_sio2.in", + "url": "silica/nanoporous_sio2/nanoporous_sio2.in" + }, + { + "fileName": "nanoporous_sio2.data", + "url": "silica/nanoporous_sio2/nanoporous_sio2.data" + }, + { + "fileName": "SiO2.vashishta", + "url": "silica/nanoporous_sio2/SiO2.vashishta" + } + ] + }, + { + "id": "generate_nanoporous", + "title": "Generate nanoporous silica", + "description": "Generate a nanoporous silica structure from betacristobalite using the vashishta potential.", + "imageUrl": "silica/generate_nanoporous/generate_nanoporous.png", + "inputScript": "generate_nanoporous.in", + "keywords": ["vashishta", "sio2", "amorphous", "nanoporous"], + "files": [ + { + "fileName": "SiO2.vashishta", + "url": "silica/generate_nanoporous/SiO2.vashishta" + }, + { + "fileName": "generate_nanoporous.in", + "url": "silica/generate_nanoporous/generate_nanoporous.in" + }, + { + "fileName": "betacristobalite.data", + "url": "silica/generate_nanoporous/betacristobalite.data" + } + ] + }, + { + "id": "reax_cho", + "title": "Hydrocarbon oxcidation", + "description": "Hydrocarbons (such as pentane) will at high temperatures react with oxygen and form water, CO, CO2, HO2 and OH. After around 3000 timesteps, we see some interesting reactions forming new molecules.", + "imageUrl": "reaxff/CHO/CHO.png", + "inputScript": "CHO.in", + "keywords": ["reaxff", "hydrocarbon", "pentane", "water"], + "files": [ + { + "fileName": "lmp_control", + "url": "reaxff/CHO/lmp_control" + }, + { + "fileName": "CHO.in", + "url": "reaxff/CHO/CHO.in" + }, + { + "fileName": "ffield.reax.cho", + "url": "reaxff/CHO/ffield.reax.cho" + }, + { + "fileName": "data.CHO", + "url": "reaxff/CHO/data.CHO" + }, + { + "fileName": "param.qeq", + "url": "reaxff/CHO/param.qeq" + } + ] + }, + { + "id": "sic_nanoparticle", + "title": "SiC nanoparticle", + "description": "A silicon carbide (SiC) nano particle in a carbon gas. The whole system is neutral, but initially, the particle has net charge. In this simulation, you can observe how the carbon gas attaches to the surface. The system cools down from 2200 K to 500 K.", + "imageUrl": "sic/nanoparticle/nanoparticle.png", + "inputScript": "nanoparticle.in", + "keywords": ["vashishta", "sic", "nanoparticle"], + "files": [ + { + "fileName": "nanoparticle.in", + "url": "sic/nanoparticle/nanoparticle.in" + }, + { + "fileName": "make_stoichiometric.in", + "url": "sic/nanoparticle/make_stoichiometric.in" + }, + { + "fileName": "SiC.vashishta", + "url": "sic/nanoparticle/SiC.vashishta" + }, + { + "fileName": "siliconcarbide.data", + "url": "sic/nanoparticle/siliconcarbide.data" + } + ] + }, + { + "id": "sic_faceted_nanoparticle", + "title": "Faceted SiC nanoparticle", + "description": "A faceted SiC nano particle. All facets are of the same type (110 planes), but due a nucleation barrier during a volume conserving shape change (see Mullins, Rohrer 2000) two of the surfaces are prevented from reaching equilibrium.", + "imageUrl": "sic/faceted_nanoparticle/faceted_nanoparticle.png", + "inputScript": "faceted_nanoparticle.in", + "keywords": ["vashishta", "sic", "nanoparticle"], + "files": [ + { + "fileName": "faceted_nanoparticle.in", + "url": "sic/faceted_nanoparticle/faceted_nanoparticle.in" + }, + { + "fileName": "SiC.vashishta", + "url": "sic/faceted_nanoparticle/SiC.vashishta" + }, + { + "fileName": "sic_nanoparticle.data", + "url": "sic/faceted_nanoparticle/sic_nanoparticle.data" + } + ] + }, + { + "id": "singlewater", + "title": "Single water molecule", + "description": "A single water molecule using the vashishta potential.", + "imageUrl": "water/singlewater/singlewater.png", + "inputScript": "singlewater.in", + "keywords": ["vashishta", "water"], + "files": [ + { + "fileName": "singlewater.data", + "url": "water/singlewater/singlewater.data" + }, + { + "fileName": "singlewater.in", + "url": "water/singlewater/singlewater.in" + }, + { + "fileName": "H2O.vashishta", + "url": "water/singlewater/H2O.vashishta" + } + ] + }, + { + "id": "watervapor", + "title": "Water vapor", + "description": "Low density water gas using the vashishta potential.", + "imageUrl": "water/vapor/vapor.png", + "inputScript": "vapor.in", + "keywords": ["vashishta", "water"], + "files": [ + { + "fileName": "vapor.data", + "url": "water/vapor/vapor.data" + }, + { + "fileName": "vapor.in", + "url": "water/vapor/vapor.in" + }, + { + "fileName": "H2O.vashishta", + "url": "water/vapor/H2O.vashishta" + } + ] + }, + { + "id": "granular_patterns", + "title": "Pattern formation in granular materials", + "description": "When particles (like sand, but really any particle) lie on a vibrating surface, there are various patterns that suddenly appear for certain values for the frequency and amplitude. In this simulation, you will see one such pattern. It might take some time, so be patient.", + "imageUrl": "granular/patterns/patterns.png", + "inputScript": "patterns.in", + "keywords": ["granular"], + "files": [ + { + "fileName": "patterns.in", + "url": "granular/patterns/patterns.in" + } + ] + }, + { + "id": "go-nanoparticle", + "title": "Graphene Oxcide nanoparticle", + "description": "The simulation consists of a single graphene oxide particle with a few water molecules. The initial GO nanoparticle has been generated using [make graphitics].", + "imageUrl": "simongravelle/solids/GO-nanoparticle/GO-nanoparticle.png", + "inputScript": "GO-nanoparticle.in", + "keywords": ["airebo", "graphene oxcide", "graphene", "simongravelle"], + "author": "Simon Gravelle", + "authorUrl": "https://simongravelle.github.io/", + "files": [ + { + "fileName": "GO-nanoparticle.in", + "url": "simongravelle/solids/GO-nanoparticle/GO-nanoparticle.in" + }, + { + "fileName": "GO-nanoparticle.data", + "url": "simongravelle/solids/GO-nanoparticle/GO-nanoparticle.data" + }, + { + "fileName": "PARM.lammps", + "url": "simongravelle/solids/GO-nanoparticle/PARM.lammps" + } + ] + }, + { + "id": "cnt_deformation", + "title": "Carbon nanotube under deformation", + "description": "The simulation consists of a single carbon nanotube (CNT) in vacuum. At the beginning of the simulation, a few atoms are removed from the CNT. The CNT is divided into three parts: the central part and the two edges. The two edges are forced to move, which leads to the gradual elongation of the CNT. Eventually, the CNT breaks. The breaking of the chemical bonds is permitted by the use of a reactive force field (AIREBO).", + "imageUrl": "simongravelle/solids/cnt-under-deformation/cnt-under-deformation.png", + "inputScript": "cnt-under-deformation.in", + "keywords": ["airebo", "cnt", "carbon nanotube", "carbon", "simongravelle"], + "author": "Simon Gravelle", + "authorUrl": "https://simongravelle.github.io/", + "files": [ + { + "fileName": "cnt-under-deformation.data", + "url": "simongravelle/solids/cnt-under-deformation/cnt-under-deformation.data" + }, + { + "fileName": "cnt-under-deformation.in", + "url": "simongravelle/solids/cnt-under-deformation/cnt-under-deformation.in" + }, + { + "fileName": "CH.airebo", + "url": "simongravelle/solids/shared/CH.airebo" + } + ] + }, + { + "id": "nacl-solution", + "title": "NaCl solution", + "description": "The simulation consists of a bulk solution of NaCl in water.", + "imageUrl": "simongravelle/liquids/nacl-solution/nacl-solution.png", + "inputScript": "nacl-solution.in", + "keywords": ["lennard jones", "salt", "water", "tip4p"], + "author": "Simon Gravelle", + "authorUrl": "https://simongravelle.github.io/", + "files": [ + { + "fileName": "nacl-solution.in", + "url": "simongravelle/liquids/nacl-solution/nacl-solution.in" + }, + { + "fileName": "nacl-solution.data", + "url": "simongravelle/liquids/nacl-solution/nacl-solution.data" + }, + { + "fileName": "PARM.lammps", + "url": "simongravelle/liquids/nacl-solution/PARM.lammps" + } + ] + }, + { + "id": "reversibly-adsorbing-particles", + "title": "Adsorption combined with diffusion create pink noise in nanopore", + "description": "The simulation consists of particles diffusing inside a cylindrical nanopore. The surface of the nanopore is covered with adsorbing sites, and the particles reversibly adsorb at the inner surface of the nanopore. The adsorption/desorption processes are modelled using bond/create and bond/break commands respectively. A bond forms if a particle comes close enough to a trap. An additional harmonic potential is added to trapped particles. The wall of the cylinder is modelled using the wall/region command.", + "imageUrl": "simongravelle/interfaces/reversibly-adsorbing-particles/reversibly-adsorbing-particles.png", + "inputScript": "reversibly-adsorbing-particles.in", + "keywords": ["lennard jones", "salt", "water", "tip4p"], + "author": "Simon Gravelle", + "authorUrl": "https://simongravelle.github.io/", + "files": [ + { + "fileName": "reversibly-adsorbing-particles.in", + "url": "simongravelle/interfaces/reversibly-adsorbing-particles/reversibly-adsorbing-particles.in" + }, + { + "fileName": "reversibly-adsorbing-particles.data", + "url": "simongravelle/interfaces/reversibly-adsorbing-particles/reversibly-adsorbing-particles.data" + }, + { + "fileName": "bonds.in", + "url": "simongravelle/interfaces/reversibly-adsorbing-particles/bonds.in" + }, + { + "fileName": "groups.in", + "url": "simongravelle/interfaces/reversibly-adsorbing-particles/groups.in" + } + ] + }, + { + "id": "betacristobalite", + "title": "Silica beta cristobalite", + "description": "Beta cristobalite crystal using the vashishta potential.", + "imageUrl": "silica/betacristobalite/betacristobalite.png", + "inputScript": "betacristobalite.in", + "keywords": ["vashishta", "sio2", "crystal"], + "files": [ + { + "fileName": "betacristobalite.in", + "url": "silica/betacristobalite/betacristobalite.in" + }, + { + "fileName": "SiO2.vashishta", + "url": "silica/betacristobalite/SiO2.vashishta" + }, + { + "fileName": "betacristobalite.data", + "url": "silica/betacristobalite/betacristobalite.data" + } + ] + }, + { + "id": "zeolite_zsm5", + "title": "Zeolite ZSM-5", + "description": "Zeolite ZSM-5 using the vashishta potential.", + "imageUrl": "silica/zeolite_zsm5/zeolite_zsm5.png", + "inputScript": "zeolite_zsm5.in", + "keywords": ["vashishta", "zeolite"], + "files": [ + { + "fileName": "zeolite_zsm5.in", + "url": "silica/zeolite_zsm5/zeolite_zsm5.in" + }, + { + "fileName": "zeolite_zsm5.data", + "url": "silica/zeolite_zsm5/zeolite_zsm5.data" + }, + { + "fileName": "SiO2.vashishta", + "url": "silica/zeolite_zsm5/SiO2.vashishta" + } + ] + }, + { + "id": "crack", + "title": "Crack 2D", + "description": "Crack propagation in a 2d solid.", + "imageUrl": "lammps/crack/crack.png", + "inputScript": "crack.in", + "keywords": ["lennard jones", "crack", "2d"], + "files": [ + { + "fileName": "crack.in", + "url": "lammps/crack/crack.in" + } + ] + }, + { + "id": "flow_couette", + "title": "Couette flow 2D", + "description": "Couette flow in a 2d channel.", + "imageUrl": "lammps/flow_couette/flow_couette.png", + "inputScript": "flow_couette.in", + "keywords": ["lennard jones", "flow", "2d"], + "files": [ + { + "fileName": "flow_couette.in", + "url": "lammps/flow_couette/flow_couette.in" + } + ] + }, + { + "id": "flow_poiseuille", + "title": "Poiseuille flow 2D", + "description": "Poiseuille flow in a 2d channel.", + "imageUrl": "lammps/flow_pois/flow_pois.png", + "inputScript": "flow_pois.in", + "keywords": ["lennard jones", "flow", "2d"], + "files": [ + { + "fileName": "flow_pois.in", + "url": "lammps/flow_pois/flow_pois.in" + } + ] + }, + { + "id": "friction", + "title": "Friction 2D", + "description": "Frictional contact of spherical asperities between 2d surfaces.", + "imageUrl": "lammps/friction/friction.png", + "inputScript": "friction.in", + "keywords": ["lennard jones", "friction", "2d"], + "files": [ + { + "fileName": "friction.in", + "url": "lammps/friction/friction.in" + } + ] + }, + { + "id": "cmap", + "title": "CMAP 5-body", + "description": "CMAP 5-body contributions to CHARMM force field.", + "imageUrl": "lammps/cmap/cmap.png", + "inputScript": "in.cmap", + "keywords": ["charmm"], + "files": [ + { + "fileName": "gagg.data", + "url": "lammps/cmap/gagg.data" + }, + { + "fileName": "in.cmap", + "url": "lammps/cmap/in.cmap" + }, + { + "fileName": "charmm22.cmap", + "url": "lammps/cmap/charmm22.cmap" + } + ] + }, + { + "id": "deposit_atom", + "title": "Deposit atoms", + "description": "Deposition of atoms onto a 3d substrate.", + "imageUrl": "lammps/deposit_atom/deposit.png", + "inputScript": "in.deposit.atom", + "keywords": ["lennard jones", "deposit"], + "files": [ + { + "fileName": "in.deposit.atom", + "url": "lammps/deposit_atom/in.deposit.atom" + } + ] + }, + { + "id": "deposit_molecule", + "title": "Deposit molecules", + "description": "Deposition of molecules onto a 3d substrate.", + "imageUrl": "lammps/deposit_molecule/deposit_molecule.png", + "inputScript": "in.deposit.molecule", + "keywords": ["lennard jones", "deposit", "3d"], + "files": [ + { + "fileName": "in.deposit.molecule", + "url": "lammps/deposit_molecule/in.deposit.molecule" + }, + { + "fileName": "molecule.dimer", + "url": "lammps/deposit_molecule/molecule.dimer" + } + ] + }, + { + "id": "micelle", + "title": "Micelle", + "description": "Self-assembly of small lipid-like molecules into 2d bilayers.", + "imageUrl": "lammps/micelle/micelle.png", + "inputScript": "in.micelle", + "keywords": ["micelle"], + "files": [ + { + "fileName": "data.micelle", + "url": "lammps/micelle/data.micelle" + }, + { + "fileName": "def.micelle", + "url": "lammps/micelle/def.micelle" + }, + { + "fileName": "in.micelle", + "url": "lammps/micelle/in.micelle" + } + ] + }, + { + "id": "obstacle", + "title": "2d obstacle", + "description": "Flow around two voids in a 2d channel.", + "imageUrl": "lammps/obstacle/obstacle.png", + "inputScript": "in.obstacle", + "keywords": ["lennard jones", "flow", "2d"], + "files": [ + { + "fileName": "in.obstacle", + "url": "lammps/obstacle/in.obstacle" + } + ] + }, + { + "id": "peptide", + "title": "Peptide solvation", + "description": "Dynamics of a small solvated peptide chain (5-mer).", + "imageUrl": "lammps/peptide/peptide.png", + "inputScript": "in.peptide", + "keywords": ["peptide"], + "files": [ + { + "fileName": "in.peptide", + "url": "lammps/peptide/in.peptide" + }, + { + "fileName": "data.peptide", + "url": "lammps/peptide/data.peptide" + } + ] + }, + { + "id": "pour_2d", + "title": "2d pour.", + "description": "Pouring of granular molecules into a 2d box, then chute flow.", + "imageUrl": "lammps/pour_2d/pour_2d.png", + "inputScript": "in.pour.2d", + "keywords": ["granular", "pour", "2d"], + "files": [ + { + "fileName": "in.pour.2d", + "url": "lammps/pour_2d/in.pour.2d" + } + ] + }, + { + "id": "pour_2d_molecule", + "title": "2d molecule pour", + "description": "Pouring of granular molecules into a 2d box, then chute flow.", + "imageUrl": "lammps/pour_2d_molecule/pour_2d_molecule.png", + "inputScript": "in.pour.2d.molecule", + "keywords": ["granular", "pour", "2d"], + "files": [ + { + "fileName": "in.pour.2d.molecule", + "url": "lammps/pour_2d_molecule/in.pour.2d.molecule" + }, + { + "fileName": "molecule.vshape", + "url": "lammps/pour_2d_molecule/molecule.vshape" + } + ] + }, + { + "id": "pour_3d", + "title": "3d pour", + "description": "Pouring of granular particles into a 3d box, then chute flow.", + "imageUrl": "lammps/pour_3d/pour.png", + "inputScript": "in.pour", + "keywords": ["granular", "pour"], + "files": [ + { + "fileName": "in.pour", + "url": "lammps/pour_3d/in.pour" + } + ] + }, + { + "id": "shear", + "title": "Shear", + "description": "sideways shear applied to 2d solid.", + "imageUrl": "lammps/shear/shear.png", + "inputScript": "in.shear", + "keywords": ["lennard jones", "shear", "2d"], + "files": [ + { + "fileName": "Ni_u3.eam", + "url": "lammps/shear/Ni_u3.eam" + }, + { + "fileName": "in.shear", + "url": "lammps/shear/in.shear" + } + ] + }, + { + "id": "shear_void", + "title": "Shear with void", + "description": "Sideways shear applied to 2d solid with a void.", + "imageUrl": "lammps/shear_void/shear_void.png", + "inputScript": "in.shear.void", + "keywords": ["lennard jones", "shear", "2d"], + "files": [ + { + "fileName": "in.shear.void", + "url": "lammps/shear_void/in.shear.void" + }, + { + "fileName": "Ni_u3.eam", + "url": "lammps/shear_void/Ni_u3.eam" + } + ] + }, + { + "id": "abstract_translocation", + "title": "Polymer through hole", + "description": "This example contains a (crude and somewhat simple) example of the translocation of a (rather short) polymer through a hole in a wall, surrounded by an explicit LJ solvent.", + "imageUrl": "moltemplate/abstract_translocation/abstract_translocation.png", + "inputScript": "run.in.npt", + "keywords": ["polymer"], + "files": [ + { + "fileName": "run.in.npt", + "url": "moltemplate/abstract_translocation/run.in.npt" + }, + { + "fileName": "system.in", + "url": "moltemplate/abstract_translocation/system.in" + }, + { + "fileName": "system.in.init", + "url": "moltemplate/abstract_translocation/system.in.init" + }, + { + "fileName": "system.in.settings", + "url": "moltemplate/abstract_translocation/system.in.settings" + }, + { + "fileName": "run.in.nvt", + "url": "moltemplate/abstract_translocation/run.in.nvt" + }, + { + "fileName": "system.data", + "url": "moltemplate/abstract_translocation/system.data" + } + ] + }, + { + "id": "alkane_chain_single", + "title": "Alkane chain", + "description": "This example is a simple simulation of a long alkane chain, in a vacuum at room temperature using the OPLSAA force field.", + "imageUrl": "moltemplate/alkane_chain_single/alkane_chain_2.png", + "inputScript": "run.in.nvt", + "keywords": ["alkane"], + "files": [ + { + "fileName": "system_after_min.data", + "url": "moltemplate/alkane_chain_single/system_after_min.data" + }, + { + "fileName": "system.in", + "url": "moltemplate/alkane_chain_single/system.in" + }, + { + "fileName": "system.in.init", + "url": "moltemplate/alkane_chain_single/system.in.init" + }, + { + "fileName": "run.in.min", + "url": "moltemplate/alkane_chain_single/run.in.min" + }, + { + "fileName": "system.in.settings", + "url": "moltemplate/alkane_chain_single/system.in.settings" + }, + { + "fileName": "run.in.nvt", + "url": "moltemplate/alkane_chain_single/run.in.nvt" + }, + { + "fileName": "system.data", + "url": "moltemplate/alkane_chain_single/system.data" + }, + { + "fileName": "system.in.charges", + "url": "moltemplate/alkane_chain_single/system.in.charges" + } + ] + }, + { + "id": "benzene", + "title": "Benzene", + "description": "This example shows how to build a box of benzene molecules using the AMBER/GAFF force-field.", + "imageUrl": "moltemplate/benzene/benzene.png", + "inputScript": "run.in.npt", + "keywords": ["amber", "benzene"], + "files": [ + { + "fileName": "run.in.npt", + "url": "moltemplate/benzene/run.in.npt" + }, + { + "fileName": "system.in", + "url": "moltemplate/benzene/system.in" + }, + { + "fileName": "system.in.init", + "url": "moltemplate/benzene/system.in.init" + }, + { + "fileName": "system.in.settings", + "url": "moltemplate/benzene/system.in.settings" + }, + { + "fileName": "run.in.nvt", + "url": "moltemplate/benzene/run.in.nvt" + }, + { + "fileName": "system.data", + "url": "moltemplate/benzene/system.data" + } + ] + }, + { + "id": "ice_crystal", + "title": "Ice crystal", + "description": "A simulation of an ice crystal using SPCE water and the shake algorithm.", + "imageUrl": "moltemplate/ice_crystal/ice_crystal.png", + "inputScript": "run.in.npt", + "keywords": ["spce", "water", "ice", "shake"], + "files": [ + { + "fileName": "run.in.npt", + "url": "moltemplate/ice_crystal/run.in.npt" + }, + { + "fileName": "system.in", + "url": "moltemplate/ice_crystal/system.in" + }, + { + "fileName": "system_after_npt.data", + "url": "moltemplate/ice_crystal/system_after_npt.data" + }, + { + "fileName": "system.in.init", + "url": "moltemplate/ice_crystal/system.in.init" + }, + { + "fileName": "system.in.settings", + "url": "moltemplate/ice_crystal/system.in.settings" + }, + { + "fileName": "run.in.nvt", + "url": "moltemplate/ice_crystal/run.in.nvt" + }, + { + "fileName": "system.data", + "url": "moltemplate/ice_crystal/system.data" + } + ] + }, + { + "id": "methane", + "title": "Methane", + "description": "This example demonstrates how to build a simulation containing a box of methane.", + "imageUrl": "moltemplate/methane/methane.png", + "inputScript": "run.in.npt", + "keywords": ["methane"], + "files": [ + { + "fileName": "run.in.npt", + "url": "moltemplate/methane/run.in.npt" + }, + { + "fileName": "system_after_min.data", + "url": "moltemplate/methane/system_after_min.data" + }, + { + "fileName": "system.in", + "url": "moltemplate/methane/system.in" + }, + { + "fileName": "system.in.init", + "url": "moltemplate/methane/system.in.init" + }, + { + "fileName": "system.in.settings", + "url": "moltemplate/methane/system.in.settings" + }, + { + "fileName": "run.in.nvt", + "url": "moltemplate/methane/run.in.nvt" + }, + { + "fileName": "system.data", + "url": "moltemplate/methane/system.data" + }, + { + "fileName": "system.in.charges", + "url": "moltemplate/methane/system.in.charges" + } + ] + }, + { + "id": "nanotube_water", + "title": "Water in nanotube", + "description": "This is a small version of a carbon-nanotube, water capillary system.", + "imageUrl": "moltemplate/nanotube+water/nanotube+water.png", + "inputScript": "run.in.npt", + "keywords": ["water", "cnt", "carbon nanotube"], + "files": [ + { + "fileName": "run.in.npt", + "url": "moltemplate/nanotube+water/run.in.npt" + }, + { + "fileName": "system.in", + "url": "moltemplate/nanotube+water/system.in" + }, + { + "fileName": "system.in.init", + "url": "moltemplate/nanotube+water/system.in.init" + }, + { + "fileName": "system.in.settings", + "url": "moltemplate/nanotube+water/system.in.settings" + }, + { + "fileName": "system.data", + "url": "moltemplate/nanotube+water/system.data" + } + ] + }, + { + "id": "water_methane", + "title": "Methane in water", + "description": "This example contains a mixture of SPCE water and methane. The methane molecules use OPLSAA force-field.", + "imageUrl": "moltemplate/waterSPCE+methane/waterSPCE+methane.png", + "inputScript": "run.in.npt", + "keywords": ["spce", "water", "methane"], + "files": [ + { + "fileName": "run.in.npt", + "url": "moltemplate/waterSPCE+methane/run.in.npt" + }, + { + "fileName": "system_after_min.data", + "url": "moltemplate/waterSPCE+methane/system_after_min.data" + }, + { + "fileName": "system.in", + "url": "moltemplate/waterSPCE+methane/system.in" + }, + { + "fileName": "system.in.init", + "url": "moltemplate/waterSPCE+methane/system.in.init" + }, + { + "fileName": "system.in.settings", + "url": "moltemplate/waterSPCE+methane/system.in.settings" + }, + { + "fileName": "run.in.nvt", + "url": "moltemplate/waterSPCE+methane/run.in.nvt" + }, + { + "fileName": "system.data", + "url": "moltemplate/waterSPCE+methane/system.data" + }, + { + "fileName": "system.in.charges", + "url": "moltemplate/waterSPCE+methane/system.in.charges" + } + ] + }, + { + "id": "water_nacl", + "title": "Salt water", + "description": "This example contains a mixture of SPCE water and salt (NaCl).", + "imageUrl": "moltemplate/waterSPCE+Na+Cl/waterSPCE+NA+CL.png", + "inputScript": "run.in.npt", + "keywords": ["spce", "water", "salt"], + "files": [ + { + "fileName": "run.in.npt", + "url": "moltemplate/waterSPCE+Na+Cl/run.in.npt" + }, + { + "fileName": "system.in", + "url": "moltemplate/waterSPCE+Na+Cl/system.in" + }, + { + "fileName": "system.in.init", + "url": "moltemplate/waterSPCE+Na+Cl/system.in.init" + }, + { + "fileName": "system.in.settings", + "url": "moltemplate/waterSPCE+Na+Cl/system.in.settings" + }, + { + "fileName": "run.in.nvt", + "url": "moltemplate/waterSPCE+Na+Cl/run.in.nvt" + }, + { + "fileName": "system.data", + "url": "moltemplate/waterSPCE+Na+Cl/system.data" + } + ] + }, + { + "id": "water_isobutane", + "title": "TIP3P water and isobutane", + "description": "The simulation consists of a mixture of isobutane and water. Over time (less than 1 ns), the two molecules phase-separate.", + "imageUrl": "moltemplate/waterTIP3P+isobutane/waterTIP3P+isobutane.png", + "inputScript": "run.in.npt", + "keywords": ["tip3p", "water", "isobutane"], + "files": [ + { + "fileName": "run.in.npt", + "url": "moltemplate/waterTIP3P+isobutane/run.in.npt" + }, + { + "fileName": "system.in", + "url": "moltemplate/waterTIP3P+isobutane/system.in" + }, + { + "fileName": "system.in.init", + "url": "moltemplate/waterTIP3P+isobutane/system.in.init" + }, + { + "fileName": "system.in.settings", + "url": "moltemplate/waterTIP3P+isobutane/system.in.settings" + }, + { + "fileName": "run.in.nvt", + "url": "moltemplate/waterTIP3P+isobutane/run.in.nvt" + }, + { + "fileName": "system.data", + "url": "moltemplate/waterTIP3P+isobutane/system.data" + } + ] + }, + { + "id": "reax_ab", + "title": "Ammonia-Borine (AB)", + "description": "Combustion of Ammonia-Borine (AB) can be simulated with ReaxFF. Two AB molecules meet and a H2 molecule is formed.", + "imageUrl": "reaxff/AB/AB.png", + "inputScript": "AB.in", + "keywords": ["reaxff", "combustion", "ammonia borine"], + "files": [ + { + "fileName": "lmp_control", + "url": "reaxff/AB/lmp_control" + }, + { + "fileName": "ffield.reax.AB", + "url": "reaxff/AB/ffield.reax.AB" + }, + { + "fileName": "AB.in", + "url": "reaxff/AB/AB.in" + }, + { + "fileName": "data.AB", + "url": "reaxff/AB/data.AB" + }, + { + "fileName": "param.qeq", + "url": "reaxff/AB/param.qeq" + } + ] + }, + { + "id": "reax_feoh3", + "title": "Iron(III) hydroxide", + "description": "In this simulation, we see low density Iron(III) hydroxide (Fe(OH)3) at high temperature.", + "imageUrl": "reaxff/FeOH3/FeOH3.png", + "inputScript": "FeOH3.in", + "keywords": ["reaxff", "iron hydroxide"], + "files": [ + { + "fileName": "data.FeOH3", + "url": "reaxff/FeOH3/data.FeOH3" + }, + { + "fileName": "lmp_control", + "url": "reaxff/FeOH3/lmp_control" + }, + { + "fileName": "ffield.reax.Fe_O_C_H", + "url": "reaxff/FeOH3/ffield.reax.Fe_O_C_H" + }, + { + "fileName": "FeOH3.in", + "url": "reaxff/FeOH3/FeOH3.in" + }, + { + "fileName": "param.qeq", + "url": "reaxff/FeOH3/param.qeq" + } + ] + }, + { + "id": "reax_rdf", + "title": "RDX explosive", + "description": "RDX is an organic compound normally used as an explosive, especially in world war II.", + "imageUrl": "reaxff/RDX/RDX.png", + "inputScript": "RDX.in", + "keywords": ["reaxff", "explosive"], + "files": [ + { + "fileName": "lmp_control", + "url": "reaxff/RDX/lmp_control" + }, + { + "fileName": "RDX.in", + "url": "reaxff/RDX/RDX.in" + }, + { + "fileName": "data.RDX", + "url": "reaxff/RDX/data.RDX" + }, + { + "fileName": "ffield.reax.rdx", + "url": "reaxff/RDX/ffield.reax.rdx" + }, + { + "fileName": "param.qeq", + "url": "reaxff/RDX/param.qeq" + } + ] + }, + { + "id": "reax_ssz13", + "title": "Zeolite SSZ-13", + "description": "This structure is a zeolite called SSZ-13 (or CHA) and has one of the silicon sites replaced with Aluminum and a hydrogen atom.", + "imageUrl": "reaxff/ssz_13/ssz_13.png", + "inputScript": "ssz_13.in", + "keywords": ["reaxff", "zeolite"], + "files": [ + { + "fileName": "ffield_Psofogiannakis_CuOH_2015", + "url": "reaxff/ssz_13/ffield_Psofogiannakis_CuOH_2015" + }, + { + "fileName": "ssz_13.in", + "url": "reaxff/ssz_13/ssz_13.in" + }, + { + "fileName": "CHA_wAl.data", + "url": "reaxff/ssz_13/CHA_wAl.data" + } + ] + }, + { + "id": "reax_voh", + "title": "Vanadium Oxide", + "description": "In this simulation, we see vanadium oxide being simulated using ReaxFF at high temperature.", + "imageUrl": "reaxff/VOH/VOH.png", + "inputScript": "VOH.in", + "keywords": ["reaxff", "vanadium oxide"], + "files": [ + { + "fileName": "lmp_control", + "url": "reaxff/VOH/lmp_control" + }, + { + "fileName": "ffield.reax.V_O_C_H", + "url": "reaxff/VOH/ffield.reax.V_O_C_H" + }, + { + "fileName": "data.VOH", + "url": "reaxff/VOH/data.VOH" + }, + { + "fileName": "VOH.in", + "url": "reaxff/VOH/VOH.in" + }, + { + "fileName": "param.qeq", + "url": "reaxff/VOH/param.qeq" + } + ] + }, + { + "id": "reax_znoh2", + "title": "Zn(OH)2", + "description": "In this simulation, we see Zn(OH)2 at high temperature.", + "imageUrl": "reaxff/ZnOH2/ZnOH2.png", + "inputScript": "ZnOH2.in", + "keywords": ["reaxff"], + "files": [ + { + "fileName": "ZnOH2.in", + "url": "reaxff/ZnOH2/ZnOH2.in" + }, + { + "fileName": "lmp_control", + "url": "reaxff/ZnOH2/lmp_control" + }, + { + "fileName": "data.ZnOH2", + "url": "reaxff/ZnOH2/data.ZnOH2" + }, + { + "fileName": "ffield.reax.ZnOH", + "url": "reaxff/ZnOH2/ffield.reax.ZnOH" + }, + { + "fileName": "param.qeq", + "url": "reaxff/ZnOH2/param.qeq" } - ] -} \ No newline at end of file + ] + } + ] +} diff --git a/public/manifest.json b/public/manifest.json index 9a79fb97..6f776abe 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -12,4 +12,4 @@ "display": "standalone", "theme_color": "#000000", "background_color": "#ffffff" -} \ No newline at end of file +} diff --git a/src/App.test.tsx b/src/App.test.tsx index bdb211c3..76f46576 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,6 +1,5 @@ -import { describe, it } from "vitest"; -import React from "react"; import { createRoot } from "react-dom/client"; +import { describe, it } from "vitest"; import App from "./App"; describe("App", () => { diff --git a/src/App.tsx b/src/App.tsx index b0d017f3..eba98ce8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,34 +1,36 @@ import { + AlignLeftOutlined, BorderOuterOutlined, - LineChartOutlined, - EditOutlined, - InsertRowAboveOutlined, - FileOutlined, - PlaySquareOutlined, BorderOutlined, - AlignLeftOutlined, - PlusSquareOutlined, CaretRightOutlined, CloudOutlined, - PauseOutlined, - ShareAltOutlined, + EditOutlined, + FileOutlined, + InsertRowAboveOutlined, + LineChartOutlined, MenuFoldOutlined, MenuUnfoldOutlined, + PauseOutlined, + PlaySquareOutlined, + PlusSquareOutlined, SettingOutlined, + ShareAltOutlined, } from "@ant-design/icons"; -import { useMeasure } from "react-use"; -import React, { useState, useEffect, useCallback } from "react"; import type { MenuProps } from "antd"; -import { Layout, Menu, Badge, ConfigProvider, theme } from "antd"; +import { Badge, ConfigProvider, Layout, Menu, theme } from "antd"; +import type React from "react"; +import { useCallback, useEffect, useState } from "react"; +import { useMeasure } from "react-use"; +import AutoStartSimulation from "./components/AutoStartSimulation"; import Simulation from "./components/Simulation"; import Main from "./containers/Main"; -import { useStoreActions, useStoreState } from "./hooks"; -import { track } from "./utils/metrics"; import NewSimulation from "./containers/NewSimulation"; -import ShareSimulation from "./containers/ShareSimulation"; import Settings from "./containers/Settings"; -import AutoStartSimulation from "./components/AutoStartSimulation"; +import ShareSimulation from "./containers/ShareSimulation"; +import { useStoreActions, useStoreState } from "./hooks"; import { useEmbeddedMode } from "./hooks/useEmbeddedMode"; +import { track } from "./utils/metrics"; + const { Sider } = Layout; type MenuItem = Required["items"][number]; @@ -36,16 +38,16 @@ type MenuItem = Required["items"][number]; const darkThemeConfig = { algorithm: theme.darkAlgorithm, token: { - colorPrimary: '#1890ff', + colorPrimary: "#1890ff", borderRadius: 8, - colorBgBase: '#29282d', - colorBgContainer: '#2a292f', + colorBgBase: "#29282d", + colorBgContainer: "#2a292f", fontSizeHeading1: 48, fontSizeHeading2: 36, }, components: { Menu: { - colorBgContainer: 'transparent', + colorBgContainer: "transparent", itemBorderRadius: 8, itemMarginInline: 8, itemActiveBorderWidth: 0, @@ -53,17 +55,17 @@ const darkThemeConfig = { subMenuItemBorderRadius: 8, }, Layout: { - siderBg: 'transparent', - triggerBg: '#1f1f1f', + siderBg: "transparent", + triggerBg: "#1f1f1f", }, Select: { - selectorBg: '#2a292f', - optionSelectedBg: '#2a2a2a', - colorText: '#ffffff', - colorTextPlaceholder: '#888', - colorBorder: '#3a3a3a', - } - } + selectorBg: "#2a292f", + optionSelectedBg: "#2a2a2a", + colorText: "#ffffff", + colorTextPlaceholder: "#888", + colorBorder: "#3a3a3a", + }, + }, }; function getItem( @@ -72,7 +74,7 @@ function getItem( icon?: React.ReactNode, children?: MenuItem[], onClick?: () => void, - disabled?: boolean, + disabled?: boolean ): MenuItem { return { key, @@ -93,16 +95,10 @@ const App: React.FC = () => { const running = useStoreState((state) => state.simulation.running); const simulation = useStoreState((state) => state.simulation.simulation); const selectedFile = useStoreState((state) => state.app.selectedFile); - const setSelectedFile = useStoreActions( - (actions) => actions.app.setSelectedFile, - ); - const setSelectedMenu = useStoreActions( - (actions) => actions.app.setSelectedMenu, - ); + const setSelectedFile = useStoreActions((actions) => actions.app.setSelectedFile); + const setSelectedMenu = useStoreActions((actions) => actions.app.setSelectedMenu); const preferredView = useStoreState((state) => state.app.preferredView); - const setPreferredView = useStoreActions( - (actions) => actions.app.setPreferredView, - ); + const setPreferredView = useStoreActions((actions) => actions.app.setPreferredView); const paused = useStoreState((state) => state.simulation.paused); const setPaused = useStoreActions((actions) => actions.simulation.setPaused); const selectedMenu = useStoreState((state) => state.app.selectedMenu); @@ -118,7 +114,7 @@ const App: React.FC = () => { setCollapsed(false); } }, [width]); - const editMenuLabel = "Edit " + (simulation ? simulation?.id : ""); + const editMenuLabel = `Edit ${simulation ? simulation?.id : ""}`; const runStopButtonTitle = running ? "Stop" : "Run"; const runStopButton = getItem( @@ -136,7 +132,7 @@ const App: React.FC = () => { setPreferredView("view"); } }, - simulation == null, + simulation == null ); const pauseButtonTitle = paused ? "Continue" : "Pause"; @@ -149,7 +145,7 @@ const App: React.FC = () => { setPaused(!paused); setPreferredView(selectedMenu); // This is another hack. Should really rethink menu system. }, - running === false, + running === false ); const newSimulationButton = getItem( @@ -161,12 +157,12 @@ const App: React.FC = () => { setShowNewSimulation(true); setPreferredView(selectedMenu); // This is another hack. Should really rethink menu system. }, - running, + running ); const shareSimulationButton = getItem( - Share simulation + Share simulation , "share", , @@ -175,20 +171,14 @@ const App: React.FC = () => { setShowShareSimulation(true); setPreferredView(selectedMenu); // This is another hack. Should really rethink menu system. }, - simulation == null || running, + simulation == null || running ); - const settingsButton = getItem( - "Settings", - "settings", - , - undefined, - () => { - track("Settings.Open"); - setShowSettings(true); - setPreferredView(selectedMenu); // This is another hack. Should really rethink menu system. - }, - ); + const settingsButton = getItem("Settings", "settings", , undefined, () => { + track("Settings.Open"); + setShowSettings(true); + setPreferredView(selectedMenu); // This is another hack. Should really rethink menu system. + }); const items: MenuItem[] = [ getItem("View", "view", ), @@ -200,15 +190,11 @@ const App: React.FC = () => { , simulation ? simulation.files.map((file) => { - return getItem( - file.fileName, - "file" + file.fileName, - , - ); + return getItem(file.fileName, `file${file.fileName}`, ); }) : [], undefined, - selectedFile == null, + selectedFile == null ), { type: "divider" }, newSimulationButton, @@ -222,7 +208,7 @@ const App: React.FC = () => { , undefined, undefined, - simulation == null, + simulation == null ), pauseButton, { type: "divider" }, @@ -242,7 +228,7 @@ const App: React.FC = () => { useEffect(() => { if (selectedFile) { - setSelectedMenu("file" + selectedFile.fileName); + setSelectedMenu(`file${selectedFile.fileName}`); } }, [selectedFile, setSelectedMenu]); @@ -255,7 +241,12 @@ const App: React.FC = () => { paused, }); - if (selected === "run" || selected === "settings" || selected === "newsimulation" || selected === "share") { + if ( + selected === "run" || + selected === "settings" || + selected === "newsimulation" || + selected === "share" + ) { return; } @@ -264,16 +255,14 @@ const App: React.FC = () => { // Oh god this is ugly const fileName = selected.substring(4); const files = simulation?.files; - const selectedFile = files?.filter( - (file) => file.fileName === fileName, - )[0]; + const selectedFile = files?.filter((file) => file.fileName === fileName)[0]; if (selectedFile) { setSelectedFile(selectedFile); } } }, - [simulation, setSelectedFile, running, paused, setSelectedMenu], + [simulation, setSelectedFile, running, paused, setSelectedMenu] ); return ( @@ -288,9 +277,18 @@ const App: React.FC = () => { onCollapse={(value) => setCollapsed(value)} trigger={null} > + {/* biome-ignore lint/a11y/useSemanticElements: Styling requires div, accessibility handled via role and keyboard events */}
setCollapsed(!collapsed)} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + setCollapsed(!collapsed); + } + }} > {collapsed ? : }
@@ -302,7 +300,7 @@ const App: React.FC = () => { mode="inline" items={items} onSelect={(info) => onMenuSelect(info.key)} - style={{ background: 'transparent' }} + style={{ background: "transparent" }} /> )} @@ -312,9 +310,7 @@ const App: React.FC = () => {
- {showNewSimulation && ( - setShowNewSimulation(false)} /> - )} + {showNewSimulation && setShowNewSimulation(false)} />} {showShareSimulation && simulation && ( { simulation={simulation} /> )} - {showSettings && ( - setShowSettings(false)} - /> - )} + {showSettings && setShowSettings(false)} />} ); }; diff --git a/src/components/AutoStartSimulation.tsx b/src/components/AutoStartSimulation.tsx index 0b92191b..bb11dc94 100644 --- a/src/components/AutoStartSimulation.tsx +++ b/src/components/AutoStartSimulation.tsx @@ -1,9 +1,9 @@ +import { notification } from "antd"; +import type React from "react"; import { useEffect, useRef } from "react"; import { useStoreActions, useStoreState } from "../hooks"; import { useEmbeddedMode } from "../hooks/useEmbeddedMode"; -import { Simulation } from "../store/simulation"; -import { notification } from "antd"; -import React from "react"; +import type { Simulation } from "../store/simulation"; import { decodeSimulation } from "../utils/embed/codec"; interface Example { @@ -30,16 +30,13 @@ interface ExamplesData { const AutoStartSimulation: React.FC = () => { const hasInitiatedStart = useRef(false); - const setNewSimulation = useStoreActions( - (actions) => actions.simulation.newSimulation - ); - const setPreferredView = useStoreActions( - (actions) => actions.app.setPreferredView - ); + const setNewSimulation = useStoreActions((actions) => actions.simulation.newSimulation); + const setPreferredView = useStoreActions((actions) => actions.app.setPreferredView); const running = useStoreState((state) => state.simulation.running); const simulation = useStoreState((state) => state.simulation.simulation); - const { embeddedSimulationUrl, simulationIndex, embeddedData, autoStart, isEmbeddedMode, vars } = useEmbeddedMode(); - + const { embeddedSimulationUrl, simulationIndex, embeddedData, autoStart, isEmbeddedMode, vars } = + useEmbeddedMode(); + useEffect(() => { const fetchAndStartSimulation = async () => { try { @@ -47,42 +44,43 @@ const AutoStartSimulation: React.FC = () => { if (embeddedData) { const decodedSimulation = decodeSimulation(embeddedData, autoStart); decodedSimulation.vars = vars; // Add URL vars - + if (simulation?.id !== decodedSimulation.id) { hasInitiatedStart.current = true; setNewSimulation(decodedSimulation); - + // Set view based on autoStart if (autoStart) { setPreferredView("view"); // Visualizer showing atoms } else { - setPreferredView("file" + decodedSimulation.inputScript); // Editor with script + setPreferredView(`file${decodedSimulation.inputScript}`); // Editor with script } } return; } - + // Handle URL-based embedding (only in embedded mode) - if (!isEmbeddedMode) { + if (!isEmbeddedMode || !embeddedSimulationUrl) { return; } - - const response = await fetch(embeddedSimulationUrl!); + + const response = await fetch(embeddedSimulationUrl); const data: ExamplesData = await response.json(); - + // Override baseUrl for localhost development // When Atomify runs on localhost, derive baseUrl from embeddedSimulationUrl - const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'; + const isLocalhost = + window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1"; if (isLocalhost && embeddedSimulationUrl) { const url = new URL(embeddedSimulationUrl); - const pathParts = url.pathname.split('/'); + const pathParts = url.pathname.split("/"); pathParts.pop(); // Remove simulations.json filename - data.baseUrl = url.origin + pathParts.join('/'); + data.baseUrl = url.origin + pathParts.join("/"); } - + if (simulationIndex >= 0 && simulationIndex < data.examples.length) { const selectedExample = data.examples[simulationIndex]; - + selectedExample.imageUrl = `${data.baseUrl}/${selectedExample.imageUrl}`; if (selectedExample.analysisScript) { selectedExample.analysisScript = `${data.baseUrl}/${selectedExample.analysisScript}`; @@ -98,7 +96,7 @@ const AutoStartSimulation: React.FC = () => { analysisDescription: selectedExample.analysisDescription, analysisScript: selectedExample.analysisScript, start: true, - vars: vars // Add URL vars + vars: vars, // Add URL vars }; if (simulation?.id !== newSimulation.id) { @@ -128,7 +126,18 @@ const AutoStartSimulation: React.FC = () => { }; checkWasmAndStart(); - }, [simulation?.id, running, setNewSimulation, setPreferredView, embeddedSimulationUrl, embeddedData, autoStart, isEmbeddedMode, simulationIndex, vars]); + }, [ + simulation?.id, + running, + setNewSimulation, + setPreferredView, + embeddedSimulationUrl, + embeddedData, + autoStart, + isEmbeddedMode, + simulationIndex, + vars, + ]); return null; }; diff --git a/src/components/ColorLegend.test.tsx b/src/components/ColorLegend.test.tsx index 46ae21c7..355eb46e 100644 --- a/src/components/ColorLegend.test.tsx +++ b/src/components/ColorLegend.test.tsx @@ -1,5 +1,5 @@ -import { describe, it, expect, beforeEach, vi } from "vitest"; import { render, screen } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import ColorLegend from "./ColorLegend"; describe("ColorLegend", () => { @@ -12,7 +12,9 @@ describe("ColorLegend", () => { fillRect: vi.fn(), }; - HTMLCanvasElement.prototype.getContext = vi.fn(() => mockContext) as unknown as typeof HTMLCanvasElement.prototype.getContext; + HTMLCanvasElement.prototype.getContext = vi.fn( + () => mockContext + ) as unknown as typeof HTMLCanvasElement.prototype.getContext; }); describe("rendering", () => { diff --git a/src/components/ColorLegend.tsx b/src/components/ColorLegend.tsx index 71c9bad0..629f4fb7 100644 --- a/src/components/ColorLegend.tsx +++ b/src/components/ColorLegend.tsx @@ -1,6 +1,6 @@ -import { useEffect, useRef } from "react"; -import colormap from "colormap"; import { SettingOutlined } from "@ant-design/icons"; +import colormap from "colormap"; +import { useEffect, useRef } from "react"; interface ColorLegendProps { computeName: string; @@ -11,7 +11,14 @@ interface ColorLegendProps { onSettingsClick?: () => void; } -const ColorLegend = ({ computeName, minValue, maxValue, type, colormap: colormapName = "jet", onSettingsClick }: ColorLegendProps) => { +const ColorLegend = ({ + computeName, + minValue, + maxValue, + type, + colormap: colormapName = "jet", + onSettingsClick, +}: ColorLegendProps) => { const canvasRef = useRef(null); useEffect(() => { @@ -34,7 +41,7 @@ const ColorLegend = ({ computeName, minValue, maxValue, type, colormap: colormap // Create gradient const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0); - + colors.forEach((color, index) => { const position = index / (colors.length - 1); const r = Math.floor(color[0] * 255); @@ -49,7 +56,7 @@ const ColorLegend = ({ computeName, minValue, maxValue, type, colormap: colormap }, [colormapName]); const formatValue = (value: number): string => { - if (!isFinite(value)) { + if (!Number.isFinite(value)) { return "N/A"; } // Format to 3 significant figures diff --git a/src/components/Figure.test.tsx b/src/components/Figure.test.tsx index 45dbf65c..abe5c8cc 100644 --- a/src/components/Figure.test.tsx +++ b/src/components/Figure.test.tsx @@ -1,7 +1,14 @@ -import { describe, it, expect, vi, beforeEach } from "vitest"; -import { render, screen, act } from "@testing-library/react"; +import { act, render, screen } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { + type Compute, + type Fix, + type LMPModifier, + ModifierType, + type PlotData, + type Variable, +} from "../types"; import Figure from "./Figure"; -import { Compute, Fix, Variable, PlotData, LMPModifier, ModifierType } from "../types"; // Mock useStoreState hook vi.mock("../hooks", () => ({ @@ -21,9 +28,30 @@ vi.mock("dygraphs", () => { // Mock antd Modal and Empty components vi.mock("antd", () => ({ - Modal: ({ children, open, onCancel }: { children: React.ReactNode; open: boolean; onCancel: () => void }) => ( - open ?
{children}
: null - ), + Modal: ({ + children, + open, + onCancel, + }: { + children: React.ReactNode; + open: boolean; + onCancel: () => void; + }) => + open ? ( +
{ + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + onCancel(); + } + }} + > + {children} +
+ ) : null, Empty: () =>
Empty
, })); @@ -32,7 +60,7 @@ describe("Figure", () => { let mockOnToggleSyncDataPoints: ( name: string, type: "compute" | "fix" | "variable", - value: boolean, + value: boolean ) => void; beforeEach(() => { @@ -73,7 +101,10 @@ describe("Figure", () => { hasScalarData: true, scalarValue: 1.0, data1D: { - data: [[0, 1], [1, 2]], + data: [ + [0, 1], + [1, 2], + ], labels: ["x", "y"], }, xLabel: "Time", @@ -95,7 +126,10 @@ describe("Figure", () => { hasScalarData: true, scalarValue: 1.0, data1D: { - data: [[0, 1], [1, 2]], + data: [ + [0, 1], + [1, 2], + ], labels: ["x", "y"], }, xLabel: "Time", @@ -117,7 +151,10 @@ describe("Figure", () => { hasScalarData: true, scalarValue: 1.0, data1D: { - data: [[0, 1], [1, 2]], + data: [ + [0, 1], + [1, 2], + ], labels: ["x", "y"], }, xLabel: "Time", @@ -134,7 +171,10 @@ describe("Figure", () => { const createMockPlotData = (overrides?: Partial): PlotData => ({ name: "test-plot", data1D: { - data: [[0, 1], [1, 2]], + data: [ + [0, 1], + [1, 2], + ], labels: ["x", "y"], }, xLabel: "Time", @@ -233,12 +273,7 @@ describe("Figure", () => { const plotData = createMockPlotData(); // Act - render( -
- ); + render(
); // Assert expect(mockOnToggleSyncDataPoints).not.toHaveBeenCalled(); @@ -249,13 +284,7 @@ describe("Figure", () => { const modifier = createMockCompute(); // Act - render( -
- ); + render(
); // Assert expect(mockOnToggleSyncDataPoints).not.toHaveBeenCalled(); @@ -325,4 +354,3 @@ describe("Figure", () => { }); }); }); - diff --git a/src/components/Figure.tsx b/src/components/Figure.tsx index 01e140f3..9daa74e4 100644 --- a/src/components/Figure.tsx +++ b/src/components/Figure.tsx @@ -1,15 +1,15 @@ -import { Modal, Empty } from "antd"; -import { Compute, Fix, Variable, PlotData } from "../types"; -import { useEffect, useState, useId, useMemo, useRef } from "react"; -import { useStoreState } from "../hooks"; +import { Empty, Modal } from "antd"; import Dygraph from "dygraphs"; +import { useEffect, useId, useMemo, useRef, useState } from "react"; +import { useStoreState } from "../hooks"; +import type { Compute, Fix, PlotData, Variable } from "../types"; type FigureProps = { onClose: () => void; onToggleSyncDataPoints?: ( name: string, type: "compute" | "fix" | "variable", - value: boolean, + value: boolean ) => void; } & ( | { @@ -34,10 +34,7 @@ const Figure = ({ const [graph, setGraph] = useState(); const timesteps = useStoreState((state) => state.simulationStatus.timesteps); const graphId = useId(); - const width = - window.innerWidth < 1000 - ? window.innerWidth * 0.8 - : window.innerWidth * 0.6; + const width = window.innerWidth < 1000 ? window.innerWidth * 0.8 : window.innerWidth * 0.6; const height = (width * 3) / 4; // Extract plot configuration from either modifier or plotData @@ -50,38 +47,29 @@ const Figure = ({ yLabel: source.yLabel, name: source.name, }; - }, [ - modifier?.name, - modifier?.xLabel, - modifier?.yLabel, - modifier?.data1D, - plotData?.name, - plotData?.xLabel, - plotData?.yLabel, - plotData?.data1D, - ]); + }, [modifier, plotData]); // Only set syncDataPoints when a modifier is provided // Use ref to track previous modifier name to detect actual changes const prevModifierNameRef = useRef(undefined); - + useEffect(() => { if (modifier && modifierType && onToggleSyncDataPoints) { const modifierName = modifier.name; const prevModifierName = prevModifierNameRef.current; - + // Only update if modifier name actually changed (not just object reference) if (prevModifierName !== modifierName) { // Cleanup previous modifier if name changed if (prevModifierName !== undefined) { onToggleSyncDataPoints(prevModifierName, modifierType, false); } - + // Set up new modifier onToggleSyncDataPoints(modifierName, modifierType, true); prevModifierNameRef.current = modifierName; } - + return () => { // Cleanup on unmount if (prevModifierNameRef.current !== undefined) { @@ -106,19 +94,19 @@ const Figure = ({ height, legend: "always", // Dark theme styling - colors: ['#40a9ff', '#52c41a', '#f5222d', '#fa8c16', '#13c2c2', '#eb2f96', '#722ed1'], - legendFormatter: function(data) { + colors: ["#40a9ff", "#52c41a", "#f5222d", "#fa8c16", "#13c2c2", "#eb2f96", "#722ed1"], + legendFormatter: (data) => { if (data.x == null) { - return ''; + return ""; } let html = '
'; - data.series.forEach(function(series) { + data.series.forEach((series) => { if (!series.isVisible) return; const color = series.color; - html += ''; - html += series.labelHTML + ': ' + series.yHTML + '
'; + html += ``; + html += `${series.labelHTML}: ${series.yHTML}
`; }); - html += '
'; + html += ""; return html; }, }); @@ -126,6 +114,7 @@ const Figure = ({ } }, [plotConfig, graph, height, width, graphId]); + // biome-ignore lint/correctness/useExhaustiveDependencies: timesteps is needed to trigger graph updates when new data points arrive useEffect(() => { if (graph && plotConfig?.data1D) { graph.updateOptions({ file: plotConfig.data1D.data }); diff --git a/src/components/LoadingSimulationScreen.tsx b/src/components/LoadingSimulationScreen.tsx index 0f1765bb..438b5a78 100644 --- a/src/components/LoadingSimulationScreen.tsx +++ b/src/components/LoadingSimulationScreen.tsx @@ -1,4 +1,4 @@ -import { Spin, Progress } from "antd"; +import { Progress, Spin } from "antd"; import styled from "styled-components"; interface LoadingSimulationScreenProps { @@ -38,11 +38,9 @@ const StatusSubtext = styled.div` margin-top: 8px; `; -const LoadingSimulationScreen = ({ - status, - wasmReady, -}: LoadingSimulationScreenProps) => { - const displayTitle = status?.title || (wasmReady ? "Loading simulation..." : "Initializing simulation engine..."); +const LoadingSimulationScreen = ({ status, wasmReady }: LoadingSimulationScreenProps) => { + const displayTitle = + status?.title || (wasmReady ? "Loading simulation..." : "Initializing simulation engine..."); const displayText = status?.text || ""; const progress = status?.progress ?? 0; diff --git a/src/components/ResponsiveSimulationSummary.test.tsx b/src/components/ResponsiveSimulationSummary.test.tsx index 64cd5285..c074448f 100644 --- a/src/components/ResponsiveSimulationSummary.test.tsx +++ b/src/components/ResponsiveSimulationSummary.test.tsx @@ -1,7 +1,7 @@ -import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen } from "@testing-library/react"; -import ResponsiveSimulationSummary from "./ResponsiveSimulationSummary"; import type { ComponentProps } from "react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import ResponsiveSimulationSummary from "./ResponsiveSimulationSummary"; import type SimulationSummary from "./SimulationSummary"; import type SimulationSummaryExpanded from "./SimulationSummaryExpanded"; @@ -9,17 +9,29 @@ import type SimulationSummaryExpanded from "./SimulationSummaryExpanded"; // Note: Using string paths for vi.mock as it's more reliable with JSX in mock factories // Type safety is maintained through ComponentProps for prop types vi.mock("./SimulationSummary", () => ({ - default: ({ - isCollapsed, - onShowMore, - onExpand, - onCollapse + default: ({ + isCollapsed, + onShowMore, + onExpand, + onCollapse, }: ComponentProps) => (
{isCollapsed &&
Collapsed
} - {onShowMore && } - {onExpand && } - {onCollapse && } + {onShowMore && ( + + )} + {onExpand && ( + + )} + {onCollapse && ( + + )}
), })); @@ -27,7 +39,11 @@ vi.mock("./SimulationSummary", () => ({ vi.mock("./SimulationSummaryExpanded", () => ({ default: ({ onShowLess }: ComponentProps) => (
- {onShowLess && } + {onShowLess && ( + + )}
), })); @@ -146,7 +162,11 @@ describe("ResponsiveSimulationSummary", () => { it("should pass isCollapsed prop to SimulationSummary", () => { // Arrange & Act render( - + ); // Assert diff --git a/src/components/ResponsiveSimulationSummary.tsx b/src/components/ResponsiveSimulationSummary.tsx index e87721a9..6b5a5ed4 100644 --- a/src/components/ResponsiveSimulationSummary.tsx +++ b/src/components/ResponsiveSimulationSummary.tsx @@ -43,11 +43,7 @@ const ResponsiveSimulationSummary = ({ // In non-embedded mode: show expanded overlay when showAnalyze is true (desktop only) if (showAnalyze && isDesktop) { - return ( - - ); + return ; } // Show regular overlay @@ -64,4 +60,3 @@ const ResponsiveSimulationSummary = ({ }; export default ResponsiveSimulationSummary; - diff --git a/src/components/SelectedAtomsInfo.tsx b/src/components/SelectedAtomsInfo.tsx index 537f58af..44e5a0e2 100644 --- a/src/components/SelectedAtomsInfo.tsx +++ b/src/components/SelectedAtomsInfo.tsx @@ -1,9 +1,9 @@ import { Button } from "antd"; -import { Particles } from "omovi"; -import { useMemo, useState, useEffect, useRef } from "react"; -import { Data1D, PlotData } from "../types"; -import Figure from "./Figure"; +import type { Particles } from "omovi"; +import { useEffect, useMemo, useRef, useState } from "react"; import { useStoreState } from "../hooks"; +import type { Data1D } from "../types"; +import Figure from "./Figure"; interface SelectedAtomsInfoProps { selectedAtoms: Set; @@ -34,14 +34,14 @@ const calculateAngle = ( // Vectors from p2 to p1 and p3 const v1 = [p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2]]; const v2 = [p3[0] - p2[0], p3[1] - p2[1], p3[2] - p2[2]]; - + // Dot product const dot = v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; - + // Magnitudes const mag1 = Math.sqrt(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]); const mag2 = Math.sqrt(v2[0] * v2[0] + v2[1] * v2[1] + v2[2] * v2[2]); - + // Angle in radians, then convert to degrees const cosAngle = dot / (mag1 * mag2); return Math.acos(Math.max(-1, Math.min(1, cosAngle))) * (180 / Math.PI); @@ -87,9 +87,16 @@ interface MeasurementRowProps { onPlotClick: (key: string) => void; } -const MeasurementRow = ({ label, value, unit, plotKey, timeSeriesData, onPlotClick }: MeasurementRowProps) => { +const MeasurementRow = ({ + label, + value, + unit, + plotKey, + timeSeriesData, + onPlotClick, +}: MeasurementRowProps) => { const hasData = timeSeriesData[plotKey]?.data.length > 0; - + return (
{hasData ? ( @@ -121,7 +128,7 @@ const SelectedAtomsInfo = ({ const prevSelectedAtomsRef = useRef>(new Set()); const prevTimestepsRef = useRef(0); const prevRunningRef = useRef(false); - + // Get running state from store const running = useStoreState((state) => state.simulation.running); @@ -129,12 +136,12 @@ const SelectedAtomsInfo = ({ useEffect(() => { const prevRunning = prevRunningRef.current; const currentRunning = running; - + // When simulation starts (running transitions from false to true), clear data if (!prevRunning && currentRunning) { setTimeSeriesData({}); } - + prevRunningRef.current = currentRunning; }, [running]); @@ -142,13 +149,13 @@ const SelectedAtomsInfo = ({ useEffect(() => { const prevSelected = prevSelectedAtomsRef.current; const currentSelected = selectedAtoms; - + // Check if selection has changed (atoms added or removed) - const selectionChanged = + const selectionChanged = prevSelected.size !== currentSelected.size || - Array.from(prevSelected).some(id => !currentSelected.has(id)) || - Array.from(currentSelected).some(id => !prevSelected.has(id)); - + Array.from(prevSelected).some((id) => !currentSelected.has(id)) || + Array.from(currentSelected).some((id) => !prevSelected.has(id)); + if (selectionChanged) { setTimeSeriesData({}); prevSelectedAtomsRef.current = new Set(currentSelected); @@ -224,9 +231,21 @@ const SelectedAtomsInfo = ({ getCanonicalAngleKey(atomPositions[2].id, atomPositions[0].id, atomPositions[1].id), ]; const angles = [ - calculateAngle(atomPositions[1].position, atomPositions[0].position, atomPositions[2].position), - calculateAngle(atomPositions[0].position, atomPositions[1].position, atomPositions[2].position), - calculateAngle(atomPositions[0].position, atomPositions[2].position, atomPositions[1].position), + calculateAngle( + atomPositions[1].position, + atomPositions[0].position, + atomPositions[2].position + ), + calculateAngle( + atomPositions[0].position, + atomPositions[1].position, + atomPositions[2].position + ), + calculateAngle( + atomPositions[0].position, + atomPositions[2].position, + atomPositions[1].position + ), ]; angleKeys.forEach((key, idx) => { @@ -256,7 +275,7 @@ const SelectedAtomsInfo = ({ if (arrayIndex === undefined) continue; const position = particles.getPosition(arrayIndex); - + data.push({ atomId, position: [position.x, position.y, position.z], @@ -291,146 +310,189 @@ const SelectedAtomsInfo = ({ )} {/* Distance for 2 atoms */} - {atomData.length === 2 && (() => { - const distanceKey = getCanonicalDistanceKey(atomData[0].atomId, atomData[1].atomId); - const distance = calculateDistance(atomData[0].position, atomData[1].position); - - return ( -
-
- Geometry + {atomData.length === 2 && + (() => { + const distanceKey = getCanonicalDistanceKey(atomData[0].atomId, atomData[1].atomId); + const distance = calculateDistance(atomData[0].position, atomData[1].position); + + return ( +
+
+ Geometry +
+
- -
- ); - })()} + ); + })()} {/* Distances and angles for 3 atoms */} - {atomData.length === 3 && (() => { - const distanceMeasurements = [ - { - label: `d(${atomData[0].atomId}-${atomData[1].atomId})`, - value: calculateDistance(atomData[0].position, atomData[1].position).toFixed(3), - unit: "Å", - plotKey: getCanonicalDistanceKey(atomData[0].atomId, atomData[1].atomId), - }, - { - label: `d(${atomData[1].atomId}-${atomData[2].atomId})`, - value: calculateDistance(atomData[1].position, atomData[2].position).toFixed(3), - unit: "Å", - plotKey: getCanonicalDistanceKey(atomData[1].atomId, atomData[2].atomId), - }, - { - label: `d(${atomData[0].atomId}-${atomData[2].atomId})`, - value: calculateDistance(atomData[0].position, atomData[2].position).toFixed(3), - unit: "Å", - plotKey: getCanonicalDistanceKey(atomData[0].atomId, atomData[2].atomId), - }, - ]; - - const angleMeasurements = [ - { - label: `∠${atomData[1].atomId}-${atomData[0].atomId}-${atomData[2].atomId}`, - value: calculateAngle(atomData[1].position, atomData[0].position, atomData[2].position).toFixed(1), - unit: "°", - plotKey: getCanonicalAngleKey(atomData[0].atomId, atomData[1].atomId, atomData[2].atomId), - }, - { - label: `∠${atomData[0].atomId}-${atomData[1].atomId}-${atomData[2].atomId}`, - value: calculateAngle(atomData[0].position, atomData[1].position, atomData[2].position).toFixed(1), - unit: "°", - plotKey: getCanonicalAngleKey(atomData[1].atomId, atomData[0].atomId, atomData[2].atomId), - }, - { - label: `∠${atomData[0].atomId}-${atomData[2].atomId}-${atomData[1].atomId}`, - value: calculateAngle(atomData[0].position, atomData[2].position, atomData[1].position).toFixed(1), - unit: "°", - plotKey: getCanonicalAngleKey(atomData[2].atomId, atomData[0].atomId, atomData[1].atomId), - }, - ]; - - return ( -
-
- Geometry -
-
- {distanceMeasurements.map((measurement, idx) => ( - - ))} -
-
- {angleMeasurements.map((measurement, idx) => ( - - ))} + {atomData.length === 3 && + (() => { + const distanceMeasurements = [ + { + label: `d(${atomData[0].atomId}-${atomData[1].atomId})`, + value: calculateDistance(atomData[0].position, atomData[1].position).toFixed(3), + unit: "Å", + plotKey: getCanonicalDistanceKey(atomData[0].atomId, atomData[1].atomId), + }, + { + label: `d(${atomData[1].atomId}-${atomData[2].atomId})`, + value: calculateDistance(atomData[1].position, atomData[2].position).toFixed(3), + unit: "Å", + plotKey: getCanonicalDistanceKey(atomData[1].atomId, atomData[2].atomId), + }, + { + label: `d(${atomData[0].atomId}-${atomData[2].atomId})`, + value: calculateDistance(atomData[0].position, atomData[2].position).toFixed(3), + unit: "Å", + plotKey: getCanonicalDistanceKey(atomData[0].atomId, atomData[2].atomId), + }, + ]; + + const angleMeasurements = [ + { + label: `∠${atomData[1].atomId}-${atomData[0].atomId}-${atomData[2].atomId}`, + value: calculateAngle( + atomData[1].position, + atomData[0].position, + atomData[2].position + ).toFixed(1), + unit: "°", + plotKey: getCanonicalAngleKey( + atomData[0].atomId, + atomData[1].atomId, + atomData[2].atomId + ), + }, + { + label: `∠${atomData[0].atomId}-${atomData[1].atomId}-${atomData[2].atomId}`, + value: calculateAngle( + atomData[0].position, + atomData[1].position, + atomData[2].position + ).toFixed(1), + unit: "°", + plotKey: getCanonicalAngleKey( + atomData[1].atomId, + atomData[0].atomId, + atomData[2].atomId + ), + }, + { + label: `∠${atomData[0].atomId}-${atomData[2].atomId}-${atomData[1].atomId}`, + value: calculateAngle( + atomData[0].position, + atomData[2].position, + atomData[1].position + ).toFixed(1), + unit: "°", + plotKey: getCanonicalAngleKey( + atomData[2].atomId, + atomData[0].atomId, + atomData[1].atomId + ), + }, + ]; + + return ( +
+
+ Geometry +
+
+ {distanceMeasurements.map((measurement) => ( + + ))} +
+
+ {angleMeasurements.map((measurement) => ( + + ))} +
-
- ); - })()} + ); + })()} - - -
+ +
Hold shift to select more particles
{/* Plot modals */} - {visiblePlot && timeSeriesData[visiblePlot] && (() => { - const getPlotName = (key: string): string => { - if (key.startsWith("distance-")) { - const ids = key.replace("distance-", "").split("-"); - return `Distance ${ids[0]}-${ids[1]}`; - } else if (key.startsWith("angle-")) { - const ids = key.replace("angle-", "").split("-"); - return `Angle ${ids[0]}-${ids[1]}-${ids[2]}`; - } - return key; - }; - - return ( -
setVisiblePlot(null)} - /> - ); - })()} + {visiblePlot && + timeSeriesData[visiblePlot] && + (() => { + const getPlotName = (key: string): string => { + if (key.startsWith("distance-")) { + const ids = key.replace("distance-", "").split("-"); + return `Distance ${ids[0]}-${ids[1]}`; + } else if (key.startsWith("angle-")) { + const ids = key.replace("angle-", "").split("-"); + return `Angle ${ids[0]}-${ids[1]}-${ids[2]}`; + } + return key; + }; + + return ( +
setVisiblePlot(null)} + /> + ); + })()}
); }; export default SelectedAtomsInfo; - diff --git a/src/components/Simulation.tsx b/src/components/Simulation.tsx index b2d4c049..34fc2457 100644 --- a/src/components/Simulation.tsx +++ b/src/components/Simulation.tsx @@ -1,10 +1,8 @@ +import { notification } from "antd"; import { useCallback, useEffect, useRef } from "react"; import { useStoreActions, useStoreState } from "../hooks"; -import createModule from "../wasm/lammps.mjs"; -import { LammpsWeb } from "../types"; -import { AtomifyWasmModule } from "../wasm/types"; -import { notification } from "antd"; import { time_event, track } from "../utils/metrics"; +import createModule from "../wasm/lammps.mjs"; const SimulationComponent = () => { const wasm = window.wasm; @@ -12,27 +10,19 @@ const SimulationComponent = () => { const simulation = useStoreState((state) => state.simulation.simulation); const paused = useStoreState((state) => state.simulation.paused); const setPaused = useStoreActions((actions) => actions.simulation.setPaused); - const simulationSettings = useStoreState( - (state) => state.settings.simulation, - ); - const setSimulationSettings = useStoreActions( - (actions) => actions.settings.setSimulation, - ); + const simulationSettings = useStoreState((state) => state.settings.simulation); + const setSimulationSettings = useStoreActions((actions) => actions.settings.setSimulation); const running = useStoreState((state) => state.simulation.running); - const addLammpsOutput = useStoreActions( - (actions) => actions.simulation.addLammpsOutput, - ); + const addLammpsOutput = useStoreActions((actions) => actions.simulation.addLammpsOutput); const selectedMenu = useStoreState((state) => state.app.selectedMenu); const setLammps = useStoreActions((actions) => actions.simulation.setLammps); const setStatus = useStoreActions((actions) => actions.app.setStatus); - const runPostTimestep = useStoreActions( - (actions) => actions.processing.runPostTimestep, - ); + const runPostTimestep = useStoreActions((actions) => actions.processing.runPostTimestep); const runPostTimestepRendering = useStoreActions( - (actions) => actions.processing.runPostTimestepRendering, + (actions) => actions.processing.runPostTimestepRendering ); const setHasSynchronized = useStoreActions( - (actions) => actions.simulationStatus.setHasSynchronized, + (actions) => actions.simulationStatus.setHasSynchronized ); const renderCycleCounter = useRef(0); @@ -45,7 +35,7 @@ const SimulationComponent = () => { addLammpsOutput(text); console.log(text); }, - [addLammpsOutput], + [addLammpsOutput] ); useEffect(() => { @@ -88,16 +78,7 @@ const SimulationComponent = () => { }); } }; - }, [ - lammps, - running, - selectedMenu, - paused, - setPaused, - setSimulationSettings, - simulation, - simulationSettings, - ]); + }, [running, selectedMenu, paused, setPaused, setSimulationSettings, simulationSettings]); useEffect(() => { window.postStepCallback = () => { @@ -107,10 +88,10 @@ const SimulationComponent = () => { } if (lammps && wasm && simulation) { setHasSynchronized(true); - + // Always update 3D rendering (high frequency) runPostTimestepRendering(); - + // Update UI state only every Nth cycle (low frequency) renderCycleCounter.current += 1; const uiUpdateFrequency = simulationSettings.uiUpdateFrequency || 15; @@ -155,11 +136,11 @@ const SimulationComponent = () => { print: onPrint, printErr: onPrint, locateFile: (path: string) => { - if (path.endsWith('.wasm')) { + if (path.endsWith(".wasm")) { return import.meta.env.BASE_URL + path; } return path; - } + }, }).then((Module) => { track("WASM.Load"); setStatus({ @@ -178,6 +159,7 @@ const SimulationComponent = () => { }, 100); } }, [onPrint, setLammps, setStatus]); + // biome-ignore lint/complexity/noUselessFragments: Component only has side effects, needs to return valid JSX return <>; }; export default SimulationComponent; diff --git a/src/components/SimulationSummary.tsx b/src/components/SimulationSummary.tsx index ddcf5c73..d9ad91b2 100644 --- a/src/components/SimulationSummary.tsx +++ b/src/components/SimulationSummary.tsx @@ -1,6 +1,6 @@ -import { useStoreState, useStoreActions } from "../hooks"; -import { Slider, Button } from "antd"; -import { MinusOutlined, ExpandOutlined } from "@ant-design/icons"; +import { ExpandOutlined, MinusOutlined } from "@ant-design/icons"; +import { Button, Slider } from "antd"; +import { useStoreActions, useStoreState } from "../hooks"; import { track } from "../utils/metrics"; interface SimulationSummaryProps { @@ -10,29 +10,21 @@ interface SimulationSummaryProps { onCollapse?: () => void; } -const SimulationSummary = ({ - onShowMore, - isCollapsed = false, +const SimulationSummary = ({ + onShowMore, + isCollapsed = false, onExpand, - onCollapse + onCollapse, }: SimulationSummaryProps) => { - const simulationSettings = useStoreState( - (state) => state.settings.simulation, - ); - const setSimulationSettings = useStoreActions( - (actions) => actions.settings.setSimulation, - ); + const simulationSettings = useStoreState((state) => state.settings.simulation); + const setSimulationSettings = useStoreActions((actions) => actions.settings.setSimulation); const simulation = useStoreState((state) => state.simulation.simulation); const runType = useStoreState((state) => state.simulationStatus.runType); const numAtoms = useStoreState((state) => state.simulationStatus.numAtoms); const numBonds = useStoreState((state) => state.simulationStatus.numBonds); const timesteps = useStoreState((state) => state.simulationStatus.timesteps); - const remainingTime = useStoreState( - (state) => state.simulationStatus.remainingTime, - ); - const timestepsPerSecond = useStoreState( - (state) => state.simulationStatus.timestepsPerSecond, - ); + const remainingTime = useStoreState((state) => state.simulationStatus.remainingTime); + const timestepsPerSecond = useStoreState((state) => state.simulationStatus.timestepsPerSecond); const setSyncFrequency = (value: number | null) => { if (value && value > 0) { @@ -67,9 +59,7 @@ const SimulationSummary = ({
{/* No buttons when collapsed - just clickable text */}
); @@ -79,13 +69,16 @@ const SimulationSummary = ({
{simulation && ( <> -
+
{onCollapse && ( {" "} - {" " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + {` ${record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : ""}`} ); } else { @@ -142,9 +117,7 @@ const SimulationSummaryContent = () => { <> {value + " " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + (record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : "")} ); } @@ -171,10 +144,7 @@ const SimulationSummaryContent = () => { > {value} {" "} - {" " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + {` ${record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : ""}`} ); } else { @@ -182,9 +152,7 @@ const SimulationSummaryContent = () => { <> {value + " " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + (record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : "")} ); } @@ -211,10 +179,7 @@ const SimulationSummaryContent = () => { > {value} {" "} - {" " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + {` ${record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : ""}`} ); } else { @@ -222,9 +187,7 @@ const SimulationSummaryContent = () => { <> {value + " " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + (record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : "")} ); } @@ -237,7 +200,7 @@ const SimulationSummaryContent = () => { title: "Name", dataIndex: "name", key: "name", - render: (text, record) => ( + render: (text, _record) => ( {text}{" "} @@ -249,7 +212,7 @@ const SimulationSummaryContent = () => { ]; const rowSelection: TableRowSelection = { - onChange: (selectedRowKeys, selectedRows) => { + onChange: (_selectedRowKeys, selectedRows) => { modifiers.forEach((modifier) => { modifier.active = selectedRows.indexOf(modifier) >= 0; }); @@ -311,6 +274,7 @@ const SimulationSummaryContent = () => { }, ]; + // biome-ignore lint/correctness/useExhaustiveDependencies(renderSettings.showSimulationBox): needed for simulationSummaryColumns render function const simulationStatusData: SimulationSummaryType[] = useMemo(() => { if (!simulation) { return []; @@ -339,7 +303,7 @@ const SimulationSummaryContent = () => { { key: "timeremain", name: "Remaining time", - value: Math.ceil(remainingTime).toString() + " s", + value: `${Math.ceil(remainingTime).toString()} s`, }, { key: "tsps", @@ -349,7 +313,7 @@ const SimulationSummaryContent = () => { { key: "memory", name: "Memory usage", - value: (memoryUsage / 1024 / 1024).toFixed(2).toString() + " MB", + value: `${(memoryUsage / 1024 / 1024).toFixed(2).toString()} MB`, }, { key: "simulationspeed", @@ -471,4 +435,3 @@ const SimulationSummaryContent = () => { }; export default React.memo(SimulationSummaryContent); - diff --git a/src/components/SimulationSummaryExpanded.tsx b/src/components/SimulationSummaryExpanded.tsx index 90377635..000d64ca 100644 --- a/src/components/SimulationSummaryExpanded.tsx +++ b/src/components/SimulationSummaryExpanded.tsx @@ -1,16 +1,16 @@ -import { useStoreState, useStoreActions } from "../hooks"; -import { SettingOutlined, MinusOutlined } from "@ant-design/icons"; -import { Table, Row, Col, Button, Slider } from "antd"; +import { MinusOutlined, SettingOutlined } from "@ant-design/icons"; +import { Button, Col, Row, Slider, Table } from "antd"; import type { ColumnsType } from "antd/es/table"; import type { TableRowSelection } from "antd/es/table/interface"; -import { Compute, Fix, Variable } from "../types"; -import React, { useState, useMemo, useCallback } from "react"; -import Modifier from "../modifiers/modifier"; +import React, { useCallback, useMemo, useState } from "react"; +import Figure from "../components/Figure"; +import { useStoreActions, useStoreState } from "../hooks"; +import ColorModifierSettings from "../modifiers/ColorModifierSettings"; +import type ColorModifier from "../modifiers/colormodifier"; +import type Modifier from "../modifiers/modifier"; import SyncBondsSettings from "../modifiers/SyncBondsSettings"; import SyncParticlesSettings from "../modifiers/SyncParticlesSettings"; -import ColorModifierSettings from "../modifiers/ColorModifierSettings"; -import ColorModifier from "../modifiers/colormodifier"; -import Figure from "../components/Figure"; +import type { Compute, Fix, Variable } from "../types"; import { track } from "../utils/metrics"; interface SimulationSummaryType { @@ -27,59 +27,37 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp const [visibleSettings, setVisibleSettings] = useState(); const [visibleCompute, setVisibleCompute] = useState(); const [visibleFix, setVisibleFix] = useState(); - const [visibleVariable, setVisibleVariable] = useState< - Variable | undefined - >(); + const [visibleVariable, setVisibleVariable] = useState(); - const simulationSettings = useStoreState( - (state) => state.settings.simulation, - ); - const modifiers = useStoreState( - (state) => state.processing.postTimestepModifiers, - ); - const postTimestepModifiers = useStoreState( - (state) => state.processing.postTimestepModifiers, - ); + const simulationSettings = useStoreState((state) => state.settings.simulation); + const modifiers = useStoreState((state) => state.processing.postTimestepModifiers); + const postTimestepModifiers = useStoreState((state) => state.processing.postTimestepModifiers); const colorModifier = postTimestepModifiers.filter( - (modifier) => modifier.name === "Colors", + (modifier) => modifier.name === "Colors" )[0] as ColorModifier; - const selectedModifiers = postTimestepModifiers - .filter((m) => m.active) - .map((m) => m.name); + const selectedModifiers = postTimestepModifiers.filter((m) => m.active).map((m) => m.name); const simulation = useStoreState((state) => state.simulation.simulation); const runType = useStoreState((state) => state.simulationStatus.runType); const numAtoms = useStoreState((state) => state.simulationStatus.numAtoms); const numBonds = useStoreState((state) => state.simulationStatus.numBonds); const timesteps = useStoreState((state) => state.simulationStatus.timesteps); - const remainingTime = useStoreState( - (state) => state.simulationStatus.remainingTime, - ); - const timestepsPerSecond = useStoreState( - (state) => state.simulationStatus.timestepsPerSecond, - ); - const memoryUsage = useStoreState( - (state) => state.simulationStatus.memoryUsage, - ); + const remainingTime = useStoreState((state) => state.simulationStatus.remainingTime); + const timestepsPerSecond = useStoreState((state) => state.simulationStatus.timestepsPerSecond); + const memoryUsage = useStoreState((state) => state.simulationStatus.memoryUsage); - const setSimulationSettings = useStoreActions( - (actions) => actions.settings.setSimulation, - ); + const setSimulationSettings = useStoreActions((actions) => actions.settings.setSimulation); const computes = useStoreState((state) => state.simulationStatus.computes); const fixes = useStoreState((state) => state.simulationStatus.fixes); const variables = useStoreState((state) => state.simulationStatus.variables); const setModifierSyncDataPointsAction = useStoreActions( - (actions) => actions.simulationStatus.setModifierSyncDataPoints, + (actions) => actions.simulationStatus.setModifierSyncDataPoints ); const handleToggleSyncDataPoints = useCallback( - ( - name: string, - type: "compute" | "fix" | "variable", - value: boolean, - ) => { + (name: string, type: "compute" | "fix" | "variable", value: boolean) => { setModifierSyncDataPointsAction({ name, type, value }); }, - [setModifierSyncDataPointsAction], + [setModifierSyncDataPointsAction] ); const setSyncFrequency = (value: number | null) => { @@ -137,10 +115,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp > {value} {" "} - {" " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + {` ${record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : ""}`} ); } else { @@ -148,9 +123,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp <> {value + " " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + (record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : "")} ); } @@ -177,10 +150,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp > {value} {" "} - {" " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + {` ${record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : ""}`} ); } else { @@ -188,9 +158,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp <> {value + " " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + (record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : "")} ); } @@ -217,10 +185,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp > {value} {" "} - {" " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + {` ${record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : ""}`} ); } else { @@ -228,9 +193,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp <> {value + " " + - (record.hasScalarData - ? record.scalarValue.toPrecision(5).toString() - : "")} + (record.hasScalarData ? record.scalarValue.toPrecision(5).toString() : "")} ); } @@ -243,7 +206,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp title: "Name", dataIndex: "name", key: "name", - render: (text, record) => ( + render: (text, _record) => ( {text}{" "} @@ -255,7 +218,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp ]; const rowSelection: TableRowSelection = { - onChange: (selectedRowKeys, selectedRows) => { + onChange: (_selectedRowKeys, selectedRows) => { modifiers.forEach((modifier) => { modifier.active = selectedRows.indexOf(modifier) >= 0; }); @@ -329,7 +292,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp { key: "timeremain", name: "Remaining time", - value: Math.ceil(remainingTime).toString() + " s", + value: `${Math.ceil(remainingTime).toString()} s`, }, { key: "tsps", @@ -339,7 +302,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp { key: "memory", name: "Memory usage", - value: (memoryUsage / 1024 / 1024).toFixed(2).toString() + " MB", + value: `${(memoryUsage / 1024 / 1024).toFixed(2).toString()} MB`, }, { key: "simulationspeed", @@ -374,7 +337,7 @@ const SimulationSummaryExpanded = ({ onShowLess }: SimulationSummaryExpandedProp type="text" icon={} onClick={handleShowLess} - style={{ color: '#fff', padding: 0 }} + style={{ color: "#fff", padding: 0 }} />
)} diff --git a/src/components/SimulationSummaryModal.tsx b/src/components/SimulationSummaryModal.tsx index 6d0c3a8c..c12cde2c 100644 --- a/src/components/SimulationSummaryModal.tsx +++ b/src/components/SimulationSummaryModal.tsx @@ -1,6 +1,6 @@ import { Modal } from "antd"; -import SimulationSummaryContent from "./SimulationSummaryContent"; import { track } from "../utils/metrics"; +import SimulationSummaryContent from "./SimulationSummaryContent"; interface SimulationSummaryModalProps { open: boolean; @@ -28,4 +28,3 @@ const SimulationSummaryModal = ({ open, onClose }: SimulationSummaryModalProps) }; export default SimulationSummaryModal; - diff --git a/src/containers/Console.tsx b/src/containers/Console.tsx index 513250e6..122298d8 100644 --- a/src/containers/Console.tsx +++ b/src/containers/Console.tsx @@ -1,7 +1,7 @@ import Editor from "@monaco-editor/react"; +import type * as Monaco from "monaco-editor"; import { useEffect, useRef } from "react"; import { useStoreState } from "../hooks"; -import type * as Monaco from "monaco-editor"; interface ConsoleProps { width?: number | string; @@ -18,7 +18,8 @@ const Console = ({ width, height }: ConsoleProps) => { selectOnLineNumbers: true, readOnly: true, }; - + + // biome-ignore lint/correctness/useExhaustiveDependencies: lammpsOutput is needed to trigger scroll when output changes useEffect(() => { const editor = editorRef.current; if (editor) { diff --git a/src/containers/Edit.tsx b/src/containers/Edit.tsx index 927d95c6..b563d7aa 100644 --- a/src/containers/Edit.tsx +++ b/src/containers/Edit.tsx @@ -1,1414 +1,1413 @@ -import { useCallback } from "react"; -import { useStoreState } from "../hooks"; import Editor, { loader } from "@monaco-editor/react"; import type * as Monaco from "monaco-editor"; +import { useCallback } from "react"; +import { useStoreState } from "../hooks"; // Initialize Monaco loader.init().then((monaco) => { monaco.languages.register({ id: "lammps" }); monaco.languages.setMonarchTokensProvider("lammps", { - keywords: [ - "ave/correlate", - "lj/spica/coul/msm/omp", - "return", - "heat/gran", - "pair_write", - "fene/intel", - "temper", - "lj/charmm/coul/charmm/omp", - "cna/atom", - "nbond/atom", - "boundary_integral", - "airebo/intel", - "rdf", - "nodeset_to_elementset", - "movie", - "lb/momentum", - "local/gran/vtk", - "tersoff/mod/gpu", - "colloid/omp", - "atom/molecule", - "threebody/table", - "mesh/surface", - "kspace_style", - "plugin", - "write_dump", - "rebo/omp", - "thermo", - "qeq/point", - "mvv/edpd", - "colloid/gpu", - "neigh_settings", - "coul/shield", - "compute", - "scafacos", - "check/timestep/gran", - "lj/cut/thole/long", - "dpd/tstat", - "store/state", - "temp/deform/kk", - "group/group", - "dpd/fdt", - "edip/multi", - "setforce/kk", - "lj/charmm/coul/charmm", - "run_style", - "sph/taitwater/morris", - "born/coul/wolf/cs", - "yukawa/colloid", - "nvt/sllod/kk", - "sw/mod", - "lj/class2/coul/cut/soft", - "cross", - "damping/cundall", - "hbond/dreiding/lj/omp", - "aveforce", - "smd/damage", - "nve/asphere/noforce", - "rigid/npt/omp", - "smd/triangle/vertices", - "harmonic/shift/cut/omp", - "srp", - "lj/cut/coul/dsf/omp", - "read_dump", - "airebo/omp", - "minimize", - "voronoi/atom", - "rigid/nph", - "rigid/local", - "pair/local", - "nve/asphere/gpu", - "lj/cut/dipole/cut/gpu", - "coul/msm", - "kernel_bandwidth", - "tdpd/cc/atom", - "zbl/kk", - "lumped_lambda_solve", - "suffix", - "peri/lps/omp", - "coul/wolf", - "fene/expand", - "pafi", - "nm/cut/split", - "stress/mop", - "coul/wolf/omp", - "nve/kk", - "table/omp", - "lj/cut/coul/debye/dielectric/omp", - "group2ndx", - "brownian", - "neigh_modify", - "lj/cut/coul/cut/soft", - "hbond/dreiding/lj", - "tersoff/zbl", - "hybrid/overlay", - "dump_modify", - "bond/react", - "nve/bpm/sphere", - "lj/charmm/coul/charmm/kk", - "lj/cut/coul/long/dielectric/omp", - "pair", - "colvars", - "e3b", - "custom/vtk", - "equal", - "coul/diel", - "ke/multisphere", - "temp/deform", - "on_the_fly", - "hybrid", - "eim/omp", - "lj/charmm/coul/long/omp", - "vtk", - "heat", - "temp/chunk", - "smd/tlsph/num/neighs", - "multi/harmonic", - "bubble", - "neb/spin", - "wall/body/polyhedron", - "atom/adios", - "reaxff/omp", - "nvt/sllod/intel", - "precession/spin", - "pressure", - "partition", - "ave/sphere/atom/kk", - "buck/long/coul/long", - "bond", - "buck", - "third_order/kk", - "cfg/uef", - "rigid/nve/small", - "buck/coul/long/cs", - "damage/atom", - "coul/cut/global", - "reaxff/kk", - "multisphere", - "track_displacement", - "temp/rotate", - "sqdistharm", - "smd/ulsph", - "smd/ulsph/num/neighs", - "smd/tri_surface", - "off", - "pressure/uef", - "vcm/chunk", - "lj/cut/coul/debye", - "gravity", - "sna/grid", - "lj/charmm/coul/long/opt", - "lj/cut/coul/long/omp", - "dpd/kk", - "harmonic/shift", - "lj/cut/soft", - "sph/density/corr", - "lj/charmm/coul/long/soft/omp", - "lj/cut/coul/long/cs", - "smd/tlsph/stress", - "qeq/reaxff/omp", - "nve/line", - "thermal", - "gld", - "halt", - "reset_timestep", - "gran", - "msst", - "smtbq", - "force/tally", - "body/rounded/polygon", - "adp/kk", - "morse/smooth/linear/omp", - "bocs", - "yes", - "coul/long/soft/omp", - "born/coul/dsf", - "cosine/buck6d", - "sph/artVisc/tensCorr", - "lj/spica/coul/long/omp", - "source_integration", - "sph/rho/atom", - "born/coul/long/cs/gpu", - "setforce/spin", - "min_style fire", - "gran/hooke", - "computes", - "gauss/cut/omp", - "tersoff/mod/c", - "plumed", - "smd/move_tri_surf", - "amoeba/bitorsion", - "awpmd/cut", - "filter", - "lj/cut/coul/msm", - "localized_lambda", - "coul/cut/omp", - "wall/lj93", - "hybrid/kk", - "com", - "coul/long/soft", - "temp/deform/eff", - "lj/gromacs/omp", - "peri/pmb", - "lj/cut/coul/long/soft/omp", - "gauss", - "wall/gran/region", - "lj/charmm/coul/msm", - "unfix", - "pppm/disp", - "multi/lucy/rx/kk", - "morse/kk", - "internal_element_set", - "nve/omp", - "qeq/comb/omp", - "coul/cut/soft", - "coul/streitz", - "buck/gpu", - "angle/local", - "nph", - "gayberne", - "lj/gromacs/coul/gromacs", - "rebo", - "manifoldforce", - "lj/spica/omp", - "coul/long/dielectric", - "adf", - "smd/tlsph/strain", - "gaussian", - "compute_modify", - "shake/kk", - "lj/class2/gpu", - "msd", - "meam/spline/omp", - "while", - "reaxff/bonds", - "yukawa/gpu", - "tersoff/zbl/gpu", - "multisphere/break", - "lj/cut/opt", - "ttm", - "born/coul/long/cs", - "if", - "min_style sd", - "rebo/intel", - "dihedral/local", - "special", - "helix", - "tersoff/zbl/omp", - "body/local", - "smd/rho", - "bond_coeff", - "sw/mod/omp", - "dimension", - "smd/ulsph/strain/rate", - "smd/tlsph/defgrad", - "npt/eff", - "lj/spica/kk", - "fep/ta", - "nvt/sphere", - "propel/self", - "granular", - "vashishta/table/omp", - "special_bonds", - "meam", - "lj/cut/dipole/cut", - "erotate/asphere", - "lj/cut/coul/long/dielectric", - "lj/cut/kk", - "lcbop", - "adapt/fep", - "fabric", - "coul/long/cs", - "lubricateU", - "com/chunk", - "lj/charmm/coul/long/kk", - "lj/cut/coul/debye/gpu", - "temp/drude", - "lj/cut/coul/cut/dielectric", - "ke/atom/eff", - "buoyancy", - "lj/charmm/coul/charmm/implicit", - "oxrna2/excv", - "gayberne/omp", - "rigid/npt/small", - "lj/long/coul/long", - "gravity/kk", - "massflow/mesh/sieve", - "lj96/cut/gpu", - "snap", - "NULL", - "resquared", - "freeze/kk", - "temp/ramp", - "charge/regulation", - "pair_modify", - "spica", - "external", - "property/atom/tracer/stream", - "tersoff/mod/kk", - "lebedeva/z", - "gle", - "lj/cut/coul/debye/omp", - "ring", - "smd/internal/energy", - "stress/cartesian", - "eam/cd", - "oxdna/hbond", - "lj/cut/coul/msm/gpu", - "buck/coul/msm", - "lj/relres", - "continuum/weighted", - "ke/eff", - "oxdna/xstk", - "wall/region", - "orientorder/atom", - "boundary_faceset", - "heat/flux/virial/tally", - "temp/eff", - "pe/tally", - "angmom/chunk", - "coul/cut/kk", - "pppm/stagger", - "vashishta/gpu", - "qeq/reaxff/kk", - "nph/omp", - "gradients", - "thole", - "setforce", - "reset_atom_ids", - "momentum/chunk", - "deposit", - "dihedral_coeff", - "inversion/harmonic", - "table/rx", - "inertia/molecule", - "lj/cut/coul/long/kk", - "property/atom/kk", - "pppm", - "kolmogorov/crespi/z", - "spring/rg", - "particletemplate/sphere", - "nvt/sphere/omp", - "eam/alloy/gpu", - "lj/cut/thole/long/omp", - "smd/ulsph/strain", - "oxdna2/hbond", - "lj/class2/coul/long/kk", - "harmonic/omp", - "nve/gpu", - "coul/slater/cut", - "contour_integral", - "morse/omp", - "min_style spin", - "agni/omp", - "insert/rate/region", - "ipi", - "airebo/morse/intel", - "buck/coul/cut/omp", - "ke/atom", - "peri/lps", - "pair/gran/local", - "wall/ees", - "umbrella", - "gran/hooke/history", - "morse/smooth/linear", - "lj/smooth/linear", - "meso/move", - "rann", - "atc", - "nve/intel", - "cosine/kk", - "kolmogorov/crespi/full", - "temp/region/eff", - "rhok", - "nph/asphere", - "wall/lj93/kk", - "msd/chunk", - "opls/intel", - "then", - "ave/euler", - "run", - "smd/plastic/strain", - "yukawa", - "wall/body/polygon", - "lj/cut/tip4p/long/soft", - "cossq", - "lineforce", - "sph/idealgas", - "tgnvt/drude", - "imd", - "lj/charmm/coul/long", - "rx/kk", - "nharmonic", - "cosine/shift", - "orient/fcc", - "pppm/tip4p", - "wf/cut", - "cmap", - "nm/cut/coul/cut", - "improper_coeff", - "eam/omp", - "nm/cut/coul/long/omp", - "amoeba", - "tip4p/long/soft", - "morse", - "controller", - "spin/exchange", - "dipole", - "contact/atom", - "edip", - "mdpd/rhosum", - "wall/lj1043", - "spica/omp", - "lj/cut/coul/cut/dielectric/omp", - "nvt/manifold/rattle", - "kim", - "edip/omp", - "vacf", - "soft/omp", - "contact/atom/gran", - "units", - "qmmm", - "lj/cut/coul/wolf", - "lubricate/omp", - "exp6/rx", - "buck/coul/cut", - "coul/cut", - "move/mesh", - "comm_modify", - "lj/long/coul/long/omp", - "neb", - "erotate/sphere", - "lj/class2/omp", - "omega/chunk", - "lj/cut/coul/msm/omp", - "lj/gromacs/coul/gromacs/kk", - "sph/e/atom", - "coul/wolf/kk", - "molfile", - "born/coul/wolf/gpu", - "born/coul/wolf/cs/gpu", - "nve/body", - "amoeba/pitorsion", - "npt", - "lj/expand/omp", - "electron_integration", - "atom/swap", - "create", - "eff/cut", - "lj96/cut", - "saed/vtk", - "pace/kk", - "dsmc", - "rigid/meso", - "beck/gpu", - "coul/dsf/omp", - "rigid", - "npt/asphere", - "smd/adjust_dt", - "born/matrix", - "lj/charmmfsw/coul/charmmfsh", - "table", - "cosine/shift/exp/omp", - "langevin/kk", - "lj/expand", - "yukawa/colloid/gpu", - "insert/pack", - "rigid/small", - "newton", - "atomic_charge", - "dynamical_matrix", - "dpd/fdt/energy/kk", - "angle_style", - "eim", - "meam/sw/spline", - "cosine/shift/omp", - "variable", - "read_restart", - "mgpt", - "viscosity/cos", - "lj/gromacs", - "dpd/gpu", - "polymorphic", - "phonon", - "lj/gromacs/coul/gromacs/omp", - "cosine/periodic", - "coul/debye/omp", - "smd/tlsph/shape", - "lj/cut/coul/dsf", - "label", - "qbmsst", - "morse/opt", - "rigid/nve/omp", - "indent", - "eam", - "eos/cv", - "nb3b/harmonic", - "dpd/tstat/kk", - "gauss/gpu", - "mliap", - "polarize/bem/icc", - "oxrna2/hbond", - "property/atom", - "sw/intel", - "multisphere/single", - "bond/swap", - "nvt/asphere", - "efield", - "nm/cut", - "lj/spica/coul/long/gpu", - "mie/cut/gpu", - "adapt", - "lj/class2/coul/long/gpu", - "fe_md_boundary", - "grem", - "buck/omp", - "smd/hourglass/error", - "peri/pmb/omp", - "tersoff/mod/c/omp", - "bond/break", - "beck/omp", - "smd/plastic/strain/rate", - "append/atoms", - "lj/cubic", - "gromos/omp", - "nvt/gpu", - "nph/sphere/omp", - "ffl", - "for", - "uncompute", - "ti/spring", - "class2/p6", - "dynamical_matrix/kk", - "lj/class2/soft", - "oneway", - "nvt/uef", - "deform/kk", - "property/chunk", - "eam/fs", - "eam/gpu", - "harmonic/cut/omp", - "particledistribution/discrete/massbased", - "min_style fire/old", - "local/density", - "orient", - "msm", - "airebo/morse/omp", - "coul/cut/soft/omp", - "temp/partial", - "wall/gran/local", - "tip4p/long/soft/omp", - "lj/cut/coul/long/intel", - "wall/harmonic", - "tracker", - "coul/long", - "enforce2d/kk", - "cosine", - "harmonic/cut", - "quip", - "smd/ulsph/effm", - "morse/soft", - "vashishta", - "gravity/omp", - "delete_elements", - "lj/long/tip4p/long/omp", - "harmonic/kk", - "mesont/tpm", - "consistent_fe_initialization", - "gauss/cut", - "body/rounded/polyhedron", - "wall/reflect", - "zbl/gpu", - "yukawa/colloid/omp", - "table/gpu", - "edpd/temp/atom", - "saip/metal", - "flow/gauss", - "lj/cut/coul/long/soft", - "resquared/omp", - "heat/gran/conduction", - "lj/cut/dipole/long", - "temp", - "rates", - "temp/sphere", - "tip4p/long/omp", - "lj/cubic/gpu", - "nvt/kk", - "spin/dipole/cut", - "reaxff/species/kk", - "dipole/omp", - "drude", - "nphug", - "accelerate/cos", - "eam/opt", - "tad", - "temper/npt", - "tersoff/table", - "coul/dsf/gpu", - "gran/hooke/omp", - "smd/vol", - "buck/long/coul/long/omp", - "lj/sf/dipole/sf/omp", - "replicate", - "npt/body", - "mol/swap", - "gyration/shape/chunk", - "ilp/graphene/hbn", - "colloid", - "mass", - "nm/cut/coul/long", - "lj/cut/coul/cut/gpu", - "cluster/atom", - "property/global", - "numdiff/virial", - "insert/stream", - "nvt", - "lj/charmm/coul/long/soft", - "ring/omp", - "lj/cut/dipole/cut/omp", - "airebo/morse", - "initial", - "min_style quickmin", - "viscous/sphere", - "nve/dotc/langevin", - "zero", - "viscosity", - "gcmc", - "momb", - "buck/coul/long/intel", - "mvv/dpd", - "read", - "msd/molecule", - "tersoff/intel", - "coul/tt", - "molecule", - "momentum", - "hexorder/atom", - "lj/cut/coul/dsf/gpu", - "lj/charmm/coul/charmm/implicit/omp", - "tersoff/table/omp", - "reaxff", - "widom", - "mdi/qm", - "nve/sphere/kk", - "hbond/dreiding/morse/omp", - "ttm/grid", - "delete_bonds", - "drag", - "PI", - "tip4p/cut", - "sph/rhosum", - "nonlinear/omp", - "tune/kspace", - "write_coeff", - "lj/cut/coul/cut/omp", - "reset_time", - "reaxff/bonds/kk", - "poisson_solver", - "coul/long/cs/gpu", - "spring", - "opls/omp", - "print", - "lj/expand/gpu", - "morse/gpu", - "srd", - "cosine/delta", - "nve/awpmd", - "nph/asphere/omp", - "mdi", - "add_to_nodeset", - "lj/cut/tip4p/long/gpu", - "distance", - "mdpd", - "cnp/atom", - "smd", - "ehex", - "lj/class2/coul/long/omp", - "lj/cut/coul/cut/soft/omp", - "brownian/omp", - "buck/coul/cut/intel", - "drip", - "ave/atom", - "smd/hertz", - "quadrature", - "fene/nm", - "reference_potential_energy", - "nvt/omp", - "soft/gpu", - "sw/omp", - "quartic", - "oxdna2/fene", - "min_modify", - "material", - "sw/angle/table", - "sph/density/summation", - "plasticity/atom", - "cosine/omp", - "coul/cut/dielectric", - "coul/msm/omp", - "enforce2d", - "quadratic", - "kspace_modify", - "smd/contact/radius", - "class2/kk", - "lj/smooth/gpu", - "coul/long/omp", - "temp/body", - "shardlow/kk", - "fields", - "global/atom", - "oxdna2/excv", - "class2/omp", - "wall/reflect/kk", - "temp/uef", - "temp/com", - "create_box", - "lj/relres/omp", - "origin", - "nvt/body", - "python/move", - "lj/class2/coul/cut/kk", - "cvff", - "temp/rescale", - "EDGE", - "rigid/npt", - "fene", - "multi/lucy", - "fep", - "mass_matrix", - "qeq/comb", - "oxdna2/stk", - "bpm/spring", - "add_species", - "atom_modify", - "tersoff/mod/omp", - "stress/cylinder", - "angle", - "nvt/intel", - "source", - "lj/long/tip4p/long", - "sph/density/continuity", - "nve/manifold/rattle", - "smd/setvel", - "create_bonds", - "cosine/squared/omp", - "meam/spline", - "coul/cut/omp/global", - "list", - "group", - "spring/self", - "dpd", - "pour", - "peri/ves", - "qeq/dynamic", - "harmonic/intel", - "erotate/superquadric", - "particledistribution/discrete", - "displace_atoms", - "pppm/cg", - "volume_integral", - "cossq/omp", - "move", - "bond_style", - "nve/sphere", - "python/invoke", - "output", - "opls/kk", - "region", - "eam/alloy/omp", - "temp/csvr", - "ewald", - "efield/atom", - "press/berendsen", - "pimd", - "nph/body", - "torque/chunk", - "addtorque", - "lj/charmm/coul/charmm/intel", - "pace", - "rx", - "langevin/eff", - "sample_frequency", - "meam/kk", - "sw", - "charmmfsw", - "polarize/bem/gmres", - "write_data", - "smd/integrate_tlsph", - "ave/chunk", - "vector", - "lj/smooth", - "born/coul/dsf/cs", - "dpd/ext/tstat/kk", - "include", - "saed", - "lubricate/poly/omp", - "dpd/ext/tstat", - "lj/cut/coul/debye/kk", - "buck/intel", - "gauss/omp", - "hybrid/overlay/kk", - "erotate/sphere/atom", - "langevin", - "lj/cut/coul/cut/kk", - "snap/kk", - "poems", - "line/lj", - "yukawa/kk", - "sdpd/taitwater/isothermal", - "freeze", - "smd/ulsph/stress", - "sph/lj", - "table/cut", - "nve/dot", - "temperature_definition", - "python", - "pppm/disp/tip4p", - "lj/class2/coul/long", - "body/nparticle", - "nvt/sllod/omp", - "particletemplate/superquadric", - "tip4p/long", - "nve/noforce", - "beck", - "planeforce", - "change_box", - "born/coul/long/gpu", - "lj/cut/tip4p/cut/omp", - "h5md", - "lj/charmm/coul/charmm/gpu", - "kernel", - "nve/spin", - "eam/cd/old", - "born/coul/msm", - "lj/mdf", - "lj/long/coul/long/intel", - "eam/alloy", - "lj/switch3/coulgauss/long", - "sph", - "particledistribution/discrete/numberbased", - "rigid/nve", - "displace/atom", - "basal/atom", - "nve/sphere/omp", - "charmm/kk", - "improper", - "hdnnp", - "ave/spatial", - "lubricate", - "coul/long/gpu", - "buck/coul/msm/omp", - "lj/spica", - "eam/he", - "fix_modify", - "oxdna2/xstk", - "erotate", - "balance", - "lj/cut/gpu", - "mm3", - "dump", - "mie/cut", - "nph/kk", - "reaxff/species", - "ewald/disp", - "cosine/periodic/omp", - "nve/tri", - "event/displace", - "umbrella/omp", - "airebo", - "lb/viscous", - "npt/omp", - "dpd/ext", - "rigid/nvt/omp", - "image", - "sph/taitwater", - "snav/atom", - "fourier/intel", - "lj/long/coul/long/opt", - "hyper/local", - "lj/expand/coul/long", - "harmonic/shift/omp", - "store/force", - "npt/intel", - "tersoff/gpu", - "lj/gromacs/gpu", - "pe", - "true", - "erotate/multisphere", - "helix/omp", - "buck/coul/long/kk", - "nphug/omp", - "mesocnt", - "prd", - "read_data", - "oxdna/fene", - "pair_coeff", - "tersoff/mod", - "lj/class2", - "buck/coul/cut/gpu", - "lj/cut/intel", - "born/coul/wolf", - "lj/long/dipole/long", - "nvt/sllod", - "lj/cut", - "jump", - "eam/alloy/opt", - "bond_write", - "entropy/atom", - "brownian/poly", - "hybrid/scaled", - "msm/cg", - "tersoff", - "momentum/kk", - "wall/srd", - "neighbor", - "write_restart", - "lj/class2/kk", - "nve/asphere", - "dpd/intel", - "opls", - "eam/kk", - "eam/intel", - "spherical", - "comb/omp", - "min_style spin/cg", - "velocity", - "restrain", - "deform", - "fene/kk", - "coul/slater", - "echo", - "clear", - "eam/alloy/kk", - "write_atom_weights", - "multi/lucy/rx", - "chunk/spread/atom", - "lj/cut/coul/wolf/omp", - "dpd/energy", - "nve/asphere/intel", - "multi/harmonic/omp", - "evaporate", - "lj/class2/coul/long/soft", - "ave/histo", - "dielectric", - "boundary", - "sph/heatconduction", - "pair_style", - "lj/charmm/coul/long/gpu", - "restart", - "vashishta/kk", - "lj/cut/coul/long/opt", - "qeq/slater", - "remove_molecule", - "nve/superquadric", - "lj/spica/coul/msm", - "sph/stationary", - "pe/atom", - "lj/cut/tip4p/long/omp", - "fragment/atom", - "shake", - "exp6/rx/kk", - "brownian/poly/omp", - "dpd/ext/kk", - "temp/cs", - "coul/diel/omp", - "npt/sphere/omp", - "edpd", - "bond/local", - "smd/integrate_ulsph", - "heat/flux", - "shardlow", - "zbl", - "hbond/dreiding/morse", - "on", - "atom_style", - "harmonic", - "fene/expand/omp", - "equilibrium_start", - "born/omp", - "addforce", - "ti", - "temp/rescale/eff", - "snad/atom", - "lj/cut/coul/cut", - "latte", - "type", - "delete_atoms", - "timestep", - "smd/tlsph/strain/rate", - "wall/piston", - "spin", - "gayberne/gpu", - "smd/tlsph", - "slice", - "born/coul/wolf/omp", - "cosine/squared", - "lj/cut/coul/msm/dielectric", - "create_elementset", - "agni", - "dpd/fdt/energy", - "property/molecule", - "dihedral", - "ke", - "nm/cut/coul/cut/omp", - "lj/sf/dipole/sf/gpu", - "lj/cut/coul/dsf/kk", - "coul/debye/gpu", - "min_style cg", - "gyration/shape", - "time_integration", - "dpd/atom", - "tersoff/omp", - "gw", - "improper_style", - "plane", - "lj/cut/soft/omp", - "set", - "lj/cut/tip4p/long/soft/omp", - "mask_direction", - "coul/dsf/kk", - "exchange", - "temp/asphere", - "lj/cut/coul/long/gpu", - "born", - "fix_flux", - "lj/charmm/coul/long/intel", - "spin/dmi", - "box/relax", - "elif", - "charmm", - "ufm", - "class2", - "quartic/omp", - "box", - "info", - "gyration", - "couple/cfd", - "spring/chunk", - "tip4p/cut/omp", - "sna/atom", - "undump", - "nve", - "lattice", - "qeq/reaxff", - "qtb", - "wall/reflect/stochastic", - "gyration/molecule", - "buck/coul/long", - "nparticles/tracer/region", - "fourier", - "timer", - "gran/hertz/history", - "smd/wall_surface", - "soft", - "lj/spica/coul/long", - "cvff/omp", - "com/molecule", - "angle_coeff", - "lubricate/poly", - "lj/cut/tip4p/long", - "lj/charmm/coul/charmm/implicit/kk", - "lj/cut/coul/long", - "spin/neel", - "msd/nongauss", - "charmm/omp", - "INF", - "oxrna2/stk", - "massflow/mesh", - "reduce/region", - "lj/cut/coul/debye/dielectric", - "lj/class2/coul/cut", - "npt/asphere/omp", - "create_atoms", - "comb", - "bond/create", - "langevin/spin", - "hyper/global", - "lj/expand/kk", - "boundary_dynamics", - "lj/cut/tip4p/cut", - "package", - "bpm/rotational", - "third_order", - "lj/expand/coul/long/gpu", - "coul/long/kk", - "lj/smooth/omp", - "write", - "buck/mdf", - "coul/dsf", - "coord/atom/kk", - "property/atom/tracer", - "eos/table/rx", - "ave/sphere/atom", - "communicate", - "nodeset", - "comb3", - "dihedral_style", - "buck/coul/long/omp", - "coord/gran", - "sph/pressure", - "acks2/reaxff/kk", - "tfmc", - "electron/stopping", - "extep", - "rigid/small/omp", - "xrd", - "orientorder/atom/kk", - "dpd/energy/kk", - "add_molecule", - "spin/magelec", - "distharm", - "stress/atom", - "rigid/nph/omp", - "cosine/shift/exp", - "qeq/shielded", - "rigid/omp", - "dpd/omp", - "log", - "cosine/delta/omp", - "property/local", - "ke/rigid", - "acks2/reaxff", - "shell", - "hyper", - "reduce", - "coul/exclude", - "centro/atom", - "eam/alloy/intel", - "yukawa/omp", - "no", - "dipole/chunk", - "next", - "fene/omp", - "coul/cut/gpu", - "temp/profile", - "zbl/omp", - "remove_source", - "reset_mol_ids", - "adp/omp", - "ptm/atom", - "rattle", - "fourier/simple", - "cvff/intel", - "coul/debye/kk", - "sw/gpu", - "none", - "ave/correlate/long", - "inertia/chunk", - "born/gpu", - "lj/sf/dipole/sf", - "npt/cauchy", - "tmd", - "lj/cut/dipole/long/gpu", - "drude/transform/direct", - "oxrna2/coaxstk", - "nvt/asphere/omp", - "ufm/omp", - "heat/flux/tally", - "oxdna/excv", - "ufm/opt", - "gran/hooke/history/omp", - "nonlinear", - "lj/spica/gpu", - "vashishta/omp", - "npt/gpu", - "atm", - "smd/tlsph/dt", - "edpd/source", - "numdiff", - "thermo_style", - "lj/cubic/omp", - "recenter", - "table/kk", - "brownian/sphere", - "multicontact/halfspace", - "lj/charmm/coul/msm/omp", - "lb/fluid", - "thermal/conductivity", - "coord/atom", - "tri/lj", - "eos/table", - "processors", - "scale", - "lj/cut/omp", - "adp", - "nharmonic/omp", - "nvt/sllod/eff", - "oxdna2/coaxstk", - "ackland/atom", - "lj/gromacs/kk", - "nvt/eff", - "erotate/rigid", - "mesont", - "born/coul/msm/omp", - "labelmap", - "born/coul/long/omp", - "gran/hertz/history/omp", - "tersoff/kk", - "create_nodeset", - "decomposition", - "bop", - "reduce/chunk", - "sw/kk", - "property/atom/regiontracer/time", - "temp/region", - "reset_atomic_reference_positions", - "lj96/cut/omp", - "buck/coul/long/gpu", - "quadratic/omp", - "resquared/gpu", - "dt/reset", - "atom_weight", - "nvk", - "nve/limit", - "unfix_flux", - "ufm/gpu", - "fourier/omp", - "comm_style", - "rigid/nvt", - "chunk/atom", - "vashishta/table", - "nph/sphere", - "sph/t/atom", - "mscg", - "filter/corotate", - "temper/grem", - "min_style hftn", - "npt/kk", - "dpd/tstat/omp", - "dilatation/atom", - "buck6d/coul/gauss/dsf", - "mesh/surface/planar", - "langevin/drude", - "fourier/simple/omp", - "lj/smooth/linear/omp", - "dpd/tstat/gpu", - "nm/cut/omp", - "pair_interactions", - "lj/cut/tip4p/long/opt", - "netcdf", - "remove_species", - "eos/table/rx/kk", - "smatb", - "table/rx/kk", - "neighbor_skin", - "ilp/tmd", - "hma", - "buck/coul/cut/kk", - "buck/kk", - "ave/time", - "quit", - "gran/hooke/history/kk", - "harmonic/shift/cut", - "coul/wolf/cs", - "thermo_modify", - "coul/debye", - "tersoff/zbl/kk", - "gyration/chunk", - "lj/class2/coul/cut/omp", - "particletemplate/multisphere", - "oxdna/stk", - "rerun", - "fix", - "rigid/nvt/small", - "viscous", - "atom_element_map", - "temp/kk", - "born/coul/long", - "wall/gran", - "wall/region/sph", - "pe/mol/tally", - "wall/lj126", - "charmm/intel", - "temp/berendsen", - "else", - "gayberne/intel", - "false", - "oxrna2/xstk", - "wall/colloid", - "improper/local", - "npt/sphere", - "internal_quadrature", - "nve/eff", - "gromos", - ], + keywords: [ + "ave/correlate", + "lj/spica/coul/msm/omp", + "return", + "heat/gran", + "pair_write", + "fene/intel", + "temper", + "lj/charmm/coul/charmm/omp", + "cna/atom", + "nbond/atom", + "boundary_integral", + "airebo/intel", + "rdf", + "nodeset_to_elementset", + "movie", + "lb/momentum", + "local/gran/vtk", + "tersoff/mod/gpu", + "colloid/omp", + "atom/molecule", + "threebody/table", + "mesh/surface", + "kspace_style", + "plugin", + "write_dump", + "rebo/omp", + "thermo", + "qeq/point", + "mvv/edpd", + "colloid/gpu", + "neigh_settings", + "coul/shield", + "compute", + "scafacos", + "check/timestep/gran", + "lj/cut/thole/long", + "dpd/tstat", + "store/state", + "temp/deform/kk", + "group/group", + "dpd/fdt", + "edip/multi", + "setforce/kk", + "lj/charmm/coul/charmm", + "run_style", + "sph/taitwater/morris", + "born/coul/wolf/cs", + "yukawa/colloid", + "nvt/sllod/kk", + "sw/mod", + "lj/class2/coul/cut/soft", + "cross", + "damping/cundall", + "hbond/dreiding/lj/omp", + "aveforce", + "smd/damage", + "nve/asphere/noforce", + "rigid/npt/omp", + "smd/triangle/vertices", + "harmonic/shift/cut/omp", + "srp", + "lj/cut/coul/dsf/omp", + "read_dump", + "airebo/omp", + "minimize", + "voronoi/atom", + "rigid/nph", + "rigid/local", + "pair/local", + "nve/asphere/gpu", + "lj/cut/dipole/cut/gpu", + "coul/msm", + "kernel_bandwidth", + "tdpd/cc/atom", + "zbl/kk", + "lumped_lambda_solve", + "suffix", + "peri/lps/omp", + "coul/wolf", + "fene/expand", + "pafi", + "nm/cut/split", + "stress/mop", + "coul/wolf/omp", + "nve/kk", + "table/omp", + "lj/cut/coul/debye/dielectric/omp", + "group2ndx", + "brownian", + "neigh_modify", + "lj/cut/coul/cut/soft", + "hbond/dreiding/lj", + "tersoff/zbl", + "hybrid/overlay", + "dump_modify", + "bond/react", + "nve/bpm/sphere", + "lj/charmm/coul/charmm/kk", + "lj/cut/coul/long/dielectric/omp", + "pair", + "colvars", + "e3b", + "custom/vtk", + "equal", + "coul/diel", + "ke/multisphere", + "temp/deform", + "on_the_fly", + "hybrid", + "eim/omp", + "lj/charmm/coul/long/omp", + "vtk", + "heat", + "temp/chunk", + "smd/tlsph/num/neighs", + "multi/harmonic", + "bubble", + "neb/spin", + "wall/body/polyhedron", + "atom/adios", + "reaxff/omp", + "nvt/sllod/intel", + "precession/spin", + "pressure", + "partition", + "ave/sphere/atom/kk", + "buck/long/coul/long", + "bond", + "buck", + "third_order/kk", + "cfg/uef", + "rigid/nve/small", + "buck/coul/long/cs", + "damage/atom", + "coul/cut/global", + "reaxff/kk", + "multisphere", + "track_displacement", + "temp/rotate", + "sqdistharm", + "smd/ulsph", + "smd/ulsph/num/neighs", + "smd/tri_surface", + "off", + "pressure/uef", + "vcm/chunk", + "lj/cut/coul/debye", + "gravity", + "sna/grid", + "lj/charmm/coul/long/opt", + "lj/cut/coul/long/omp", + "dpd/kk", + "harmonic/shift", + "lj/cut/soft", + "sph/density/corr", + "lj/charmm/coul/long/soft/omp", + "lj/cut/coul/long/cs", + "smd/tlsph/stress", + "qeq/reaxff/omp", + "nve/line", + "thermal", + "gld", + "halt", + "reset_timestep", + "gran", + "msst", + "smtbq", + "force/tally", + "body/rounded/polygon", + "adp/kk", + "morse/smooth/linear/omp", + "bocs", + "yes", + "coul/long/soft/omp", + "born/coul/dsf", + "cosine/buck6d", + "sph/artVisc/tensCorr", + "lj/spica/coul/long/omp", + "source_integration", + "sph/rho/atom", + "born/coul/long/cs/gpu", + "setforce/spin", + "min_style fire", + "gran/hooke", + "computes", + "gauss/cut/omp", + "tersoff/mod/c", + "plumed", + "smd/move_tri_surf", + "amoeba/bitorsion", + "awpmd/cut", + "filter", + "lj/cut/coul/msm", + "localized_lambda", + "coul/cut/omp", + "wall/lj93", + "hybrid/kk", + "com", + "coul/long/soft", + "temp/deform/eff", + "lj/gromacs/omp", + "peri/pmb", + "lj/cut/coul/long/soft/omp", + "gauss", + "wall/gran/region", + "lj/charmm/coul/msm", + "unfix", + "pppm/disp", + "multi/lucy/rx/kk", + "morse/kk", + "internal_element_set", + "nve/omp", + "qeq/comb/omp", + "coul/cut/soft", + "coul/streitz", + "buck/gpu", + "angle/local", + "nph", + "gayberne", + "lj/gromacs/coul/gromacs", + "rebo", + "manifoldforce", + "lj/spica/omp", + "coul/long/dielectric", + "adf", + "smd/tlsph/strain", + "gaussian", + "compute_modify", + "shake/kk", + "lj/class2/gpu", + "msd", + "meam/spline/omp", + "while", + "reaxff/bonds", + "yukawa/gpu", + "tersoff/zbl/gpu", + "multisphere/break", + "lj/cut/opt", + "ttm", + "born/coul/long/cs", + "if", + "min_style sd", + "rebo/intel", + "dihedral/local", + "special", + "helix", + "tersoff/zbl/omp", + "body/local", + "smd/rho", + "bond_coeff", + "sw/mod/omp", + "dimension", + "smd/ulsph/strain/rate", + "smd/tlsph/defgrad", + "npt/eff", + "lj/spica/kk", + "fep/ta", + "nvt/sphere", + "propel/self", + "granular", + "vashishta/table/omp", + "special_bonds", + "meam", + "lj/cut/dipole/cut", + "erotate/asphere", + "lj/cut/coul/long/dielectric", + "lj/cut/kk", + "lcbop", + "adapt/fep", + "fabric", + "coul/long/cs", + "lubricateU", + "com/chunk", + "lj/charmm/coul/long/kk", + "lj/cut/coul/debye/gpu", + "temp/drude", + "lj/cut/coul/cut/dielectric", + "ke/atom/eff", + "buoyancy", + "lj/charmm/coul/charmm/implicit", + "oxrna2/excv", + "gayberne/omp", + "rigid/npt/small", + "lj/long/coul/long", + "gravity/kk", + "massflow/mesh/sieve", + "lj96/cut/gpu", + "snap", + "NULL", + "resquared", + "freeze/kk", + "temp/ramp", + "charge/regulation", + "pair_modify", + "spica", + "external", + "property/atom/tracer/stream", + "tersoff/mod/kk", + "lebedeva/z", + "gle", + "lj/cut/coul/debye/omp", + "ring", + "smd/internal/energy", + "stress/cartesian", + "eam/cd", + "oxdna/hbond", + "lj/cut/coul/msm/gpu", + "buck/coul/msm", + "lj/relres", + "continuum/weighted", + "ke/eff", + "oxdna/xstk", + "wall/region", + "orientorder/atom", + "boundary_faceset", + "heat/flux/virial/tally", + "temp/eff", + "pe/tally", + "angmom/chunk", + "coul/cut/kk", + "pppm/stagger", + "vashishta/gpu", + "qeq/reaxff/kk", + "nph/omp", + "gradients", + "thole", + "setforce", + "reset_atom_ids", + "momentum/chunk", + "deposit", + "dihedral_coeff", + "inversion/harmonic", + "table/rx", + "inertia/molecule", + "lj/cut/coul/long/kk", + "property/atom/kk", + "pppm", + "kolmogorov/crespi/z", + "spring/rg", + "particletemplate/sphere", + "nvt/sphere/omp", + "eam/alloy/gpu", + "lj/cut/thole/long/omp", + "smd/ulsph/strain", + "oxdna2/hbond", + "lj/class2/coul/long/kk", + "harmonic/omp", + "nve/gpu", + "coul/slater/cut", + "contour_integral", + "morse/omp", + "min_style spin", + "agni/omp", + "insert/rate/region", + "ipi", + "airebo/morse/intel", + "buck/coul/cut/omp", + "ke/atom", + "peri/lps", + "pair/gran/local", + "wall/ees", + "umbrella", + "gran/hooke/history", + "morse/smooth/linear", + "lj/smooth/linear", + "meso/move", + "rann", + "atc", + "nve/intel", + "cosine/kk", + "kolmogorov/crespi/full", + "temp/region/eff", + "rhok", + "nph/asphere", + "wall/lj93/kk", + "msd/chunk", + "opls/intel", + "then", + "ave/euler", + "run", + "smd/plastic/strain", + "yukawa", + "wall/body/polygon", + "lj/cut/tip4p/long/soft", + "cossq", + "lineforce", + "sph/idealgas", + "tgnvt/drude", + "imd", + "lj/charmm/coul/long", + "rx/kk", + "nharmonic", + "cosine/shift", + "orient/fcc", + "pppm/tip4p", + "wf/cut", + "cmap", + "nm/cut/coul/cut", + "improper_coeff", + "eam/omp", + "nm/cut/coul/long/omp", + "amoeba", + "tip4p/long/soft", + "morse", + "controller", + "spin/exchange", + "dipole", + "contact/atom", + "edip", + "mdpd/rhosum", + "wall/lj1043", + "spica/omp", + "lj/cut/coul/cut/dielectric/omp", + "nvt/manifold/rattle", + "kim", + "edip/omp", + "vacf", + "soft/omp", + "contact/atom/gran", + "units", + "qmmm", + "lj/cut/coul/wolf", + "lubricate/omp", + "exp6/rx", + "buck/coul/cut", + "coul/cut", + "move/mesh", + "comm_modify", + "lj/long/coul/long/omp", + "neb", + "erotate/sphere", + "lj/class2/omp", + "omega/chunk", + "lj/cut/coul/msm/omp", + "lj/gromacs/coul/gromacs/kk", + "sph/e/atom", + "coul/wolf/kk", + "molfile", + "born/coul/wolf/gpu", + "born/coul/wolf/cs/gpu", + "nve/body", + "amoeba/pitorsion", + "npt", + "lj/expand/omp", + "electron_integration", + "atom/swap", + "create", + "eff/cut", + "lj96/cut", + "saed/vtk", + "pace/kk", + "dsmc", + "rigid/meso", + "beck/gpu", + "coul/dsf/omp", + "rigid", + "npt/asphere", + "smd/adjust_dt", + "born/matrix", + "lj/charmmfsw/coul/charmmfsh", + "table", + "cosine/shift/exp/omp", + "langevin/kk", + "lj/expand", + "yukawa/colloid/gpu", + "insert/pack", + "rigid/small", + "newton", + "atomic_charge", + "dynamical_matrix", + "dpd/fdt/energy/kk", + "angle_style", + "eim", + "meam/sw/spline", + "cosine/shift/omp", + "variable", + "read_restart", + "mgpt", + "viscosity/cos", + "lj/gromacs", + "dpd/gpu", + "polymorphic", + "phonon", + "lj/gromacs/coul/gromacs/omp", + "cosine/periodic", + "coul/debye/omp", + "smd/tlsph/shape", + "lj/cut/coul/dsf", + "label", + "qbmsst", + "morse/opt", + "rigid/nve/omp", + "indent", + "eam", + "eos/cv", + "nb3b/harmonic", + "dpd/tstat/kk", + "gauss/gpu", + "mliap", + "polarize/bem/icc", + "oxrna2/hbond", + "property/atom", + "sw/intel", + "multisphere/single", + "bond/swap", + "nvt/asphere", + "efield", + "nm/cut", + "lj/spica/coul/long/gpu", + "mie/cut/gpu", + "adapt", + "lj/class2/coul/long/gpu", + "fe_md_boundary", + "grem", + "buck/omp", + "smd/hourglass/error", + "peri/pmb/omp", + "tersoff/mod/c/omp", + "bond/break", + "beck/omp", + "smd/plastic/strain/rate", + "append/atoms", + "lj/cubic", + "gromos/omp", + "nvt/gpu", + "nph/sphere/omp", + "ffl", + "for", + "uncompute", + "ti/spring", + "class2/p6", + "dynamical_matrix/kk", + "lj/class2/soft", + "oneway", + "nvt/uef", + "deform/kk", + "property/chunk", + "eam/fs", + "eam/gpu", + "harmonic/cut/omp", + "particledistribution/discrete/massbased", + "min_style fire/old", + "local/density", + "orient", + "msm", + "airebo/morse/omp", + "coul/cut/soft/omp", + "temp/partial", + "wall/gran/local", + "tip4p/long/soft/omp", + "lj/cut/coul/long/intel", + "wall/harmonic", + "tracker", + "coul/long", + "enforce2d/kk", + "cosine", + "harmonic/cut", + "quip", + "smd/ulsph/effm", + "morse/soft", + "vashishta", + "gravity/omp", + "delete_elements", + "lj/long/tip4p/long/omp", + "harmonic/kk", + "mesont/tpm", + "consistent_fe_initialization", + "gauss/cut", + "body/rounded/polyhedron", + "wall/reflect", + "zbl/gpu", + "yukawa/colloid/omp", + "table/gpu", + "edpd/temp/atom", + "saip/metal", + "flow/gauss", + "lj/cut/coul/long/soft", + "resquared/omp", + "heat/gran/conduction", + "lj/cut/dipole/long", + "temp", + "rates", + "temp/sphere", + "tip4p/long/omp", + "lj/cubic/gpu", + "nvt/kk", + "spin/dipole/cut", + "reaxff/species/kk", + "dipole/omp", + "drude", + "nphug", + "accelerate/cos", + "eam/opt", + "tad", + "temper/npt", + "tersoff/table", + "coul/dsf/gpu", + "gran/hooke/omp", + "smd/vol", + "buck/long/coul/long/omp", + "lj/sf/dipole/sf/omp", + "replicate", + "npt/body", + "mol/swap", + "gyration/shape/chunk", + "ilp/graphene/hbn", + "colloid", + "mass", + "nm/cut/coul/long", + "lj/cut/coul/cut/gpu", + "cluster/atom", + "property/global", + "numdiff/virial", + "insert/stream", + "nvt", + "lj/charmm/coul/long/soft", + "ring/omp", + "lj/cut/dipole/cut/omp", + "airebo/morse", + "initial", + "min_style quickmin", + "viscous/sphere", + "nve/dotc/langevin", + "zero", + "viscosity", + "gcmc", + "momb", + "buck/coul/long/intel", + "mvv/dpd", + "read", + "msd/molecule", + "tersoff/intel", + "coul/tt", + "molecule", + "momentum", + "hexorder/atom", + "lj/cut/coul/dsf/gpu", + "lj/charmm/coul/charmm/implicit/omp", + "tersoff/table/omp", + "reaxff", + "widom", + "mdi/qm", + "nve/sphere/kk", + "hbond/dreiding/morse/omp", + "ttm/grid", + "delete_bonds", + "drag", + "PI", + "tip4p/cut", + "sph/rhosum", + "nonlinear/omp", + "tune/kspace", + "write_coeff", + "lj/cut/coul/cut/omp", + "reset_time", + "reaxff/bonds/kk", + "poisson_solver", + "coul/long/cs/gpu", + "spring", + "opls/omp", + "print", + "lj/expand/gpu", + "morse/gpu", + "srd", + "cosine/delta", + "nve/awpmd", + "nph/asphere/omp", + "mdi", + "add_to_nodeset", + "lj/cut/tip4p/long/gpu", + "distance", + "mdpd", + "cnp/atom", + "smd", + "ehex", + "lj/class2/coul/long/omp", + "lj/cut/coul/cut/soft/omp", + "brownian/omp", + "buck/coul/cut/intel", + "drip", + "ave/atom", + "smd/hertz", + "quadrature", + "fene/nm", + "reference_potential_energy", + "nvt/omp", + "soft/gpu", + "sw/omp", + "quartic", + "oxdna2/fene", + "min_modify", + "material", + "sw/angle/table", + "sph/density/summation", + "plasticity/atom", + "cosine/omp", + "coul/cut/dielectric", + "coul/msm/omp", + "enforce2d", + "quadratic", + "kspace_modify", + "smd/contact/radius", + "class2/kk", + "lj/smooth/gpu", + "coul/long/omp", + "temp/body", + "shardlow/kk", + "fields", + "global/atom", + "oxdna2/excv", + "class2/omp", + "wall/reflect/kk", + "temp/uef", + "temp/com", + "create_box", + "lj/relres/omp", + "origin", + "nvt/body", + "python/move", + "lj/class2/coul/cut/kk", + "cvff", + "temp/rescale", + "EDGE", + "rigid/npt", + "fene", + "multi/lucy", + "fep", + "mass_matrix", + "qeq/comb", + "oxdna2/stk", + "bpm/spring", + "add_species", + "atom_modify", + "tersoff/mod/omp", + "stress/cylinder", + "angle", + "nvt/intel", + "source", + "lj/long/tip4p/long", + "sph/density/continuity", + "nve/manifold/rattle", + "smd/setvel", + "create_bonds", + "cosine/squared/omp", + "meam/spline", + "coul/cut/omp/global", + "list", + "group", + "spring/self", + "dpd", + "pour", + "peri/ves", + "qeq/dynamic", + "harmonic/intel", + "erotate/superquadric", + "particledistribution/discrete", + "displace_atoms", + "pppm/cg", + "volume_integral", + "cossq/omp", + "move", + "bond_style", + "nve/sphere", + "python/invoke", + "output", + "opls/kk", + "region", + "eam/alloy/omp", + "temp/csvr", + "ewald", + "efield/atom", + "press/berendsen", + "pimd", + "nph/body", + "torque/chunk", + "addtorque", + "lj/charmm/coul/charmm/intel", + "pace", + "rx", + "langevin/eff", + "sample_frequency", + "meam/kk", + "sw", + "charmmfsw", + "polarize/bem/gmres", + "write_data", + "smd/integrate_tlsph", + "ave/chunk", + "vector", + "lj/smooth", + "born/coul/dsf/cs", + "dpd/ext/tstat/kk", + "include", + "saed", + "lubricate/poly/omp", + "dpd/ext/tstat", + "lj/cut/coul/debye/kk", + "buck/intel", + "gauss/omp", + "hybrid/overlay/kk", + "erotate/sphere/atom", + "langevin", + "lj/cut/coul/cut/kk", + "snap/kk", + "poems", + "line/lj", + "yukawa/kk", + "sdpd/taitwater/isothermal", + "freeze", + "smd/ulsph/stress", + "sph/lj", + "table/cut", + "nve/dot", + "temperature_definition", + "python", + "pppm/disp/tip4p", + "lj/class2/coul/long", + "body/nparticle", + "nvt/sllod/omp", + "particletemplate/superquadric", + "tip4p/long", + "nve/noforce", + "beck", + "planeforce", + "change_box", + "born/coul/long/gpu", + "lj/cut/tip4p/cut/omp", + "h5md", + "lj/charmm/coul/charmm/gpu", + "kernel", + "nve/spin", + "eam/cd/old", + "born/coul/msm", + "lj/mdf", + "lj/long/coul/long/intel", + "eam/alloy", + "lj/switch3/coulgauss/long", + "sph", + "particledistribution/discrete/numberbased", + "rigid/nve", + "displace/atom", + "basal/atom", + "nve/sphere/omp", + "charmm/kk", + "improper", + "hdnnp", + "ave/spatial", + "lubricate", + "coul/long/gpu", + "buck/coul/msm/omp", + "lj/spica", + "eam/he", + "fix_modify", + "oxdna2/xstk", + "erotate", + "balance", + "lj/cut/gpu", + "mm3", + "dump", + "mie/cut", + "nph/kk", + "reaxff/species", + "ewald/disp", + "cosine/periodic/omp", + "nve/tri", + "event/displace", + "umbrella/omp", + "airebo", + "lb/viscous", + "npt/omp", + "dpd/ext", + "rigid/nvt/omp", + "image", + "sph/taitwater", + "snav/atom", + "fourier/intel", + "lj/long/coul/long/opt", + "hyper/local", + "lj/expand/coul/long", + "harmonic/shift/omp", + "store/force", + "npt/intel", + "tersoff/gpu", + "lj/gromacs/gpu", + "pe", + "true", + "erotate/multisphere", + "helix/omp", + "buck/coul/long/kk", + "nphug/omp", + "mesocnt", + "prd", + "read_data", + "oxdna/fene", + "pair_coeff", + "tersoff/mod", + "lj/class2", + "buck/coul/cut/gpu", + "lj/cut/intel", + "born/coul/wolf", + "lj/long/dipole/long", + "nvt/sllod", + "lj/cut", + "jump", + "eam/alloy/opt", + "bond_write", + "entropy/atom", + "brownian/poly", + "hybrid/scaled", + "msm/cg", + "tersoff", + "momentum/kk", + "wall/srd", + "neighbor", + "write_restart", + "lj/class2/kk", + "nve/asphere", + "dpd/intel", + "opls", + "eam/kk", + "eam/intel", + "spherical", + "comb/omp", + "min_style spin/cg", + "velocity", + "restrain", + "deform", + "fene/kk", + "coul/slater", + "echo", + "clear", + "eam/alloy/kk", + "write_atom_weights", + "multi/lucy/rx", + "chunk/spread/atom", + "lj/cut/coul/wolf/omp", + "dpd/energy", + "nve/asphere/intel", + "multi/harmonic/omp", + "evaporate", + "lj/class2/coul/long/soft", + "ave/histo", + "dielectric", + "boundary", + "sph/heatconduction", + "pair_style", + "lj/charmm/coul/long/gpu", + "restart", + "vashishta/kk", + "lj/cut/coul/long/opt", + "qeq/slater", + "remove_molecule", + "nve/superquadric", + "lj/spica/coul/msm", + "sph/stationary", + "pe/atom", + "lj/cut/tip4p/long/omp", + "fragment/atom", + "shake", + "exp6/rx/kk", + "brownian/poly/omp", + "dpd/ext/kk", + "temp/cs", + "coul/diel/omp", + "npt/sphere/omp", + "edpd", + "bond/local", + "smd/integrate_ulsph", + "heat/flux", + "shardlow", + "zbl", + "hbond/dreiding/morse", + "on", + "atom_style", + "harmonic", + "fene/expand/omp", + "equilibrium_start", + "born/omp", + "addforce", + "ti", + "temp/rescale/eff", + "snad/atom", + "lj/cut/coul/cut", + "latte", + "type", + "delete_atoms", + "timestep", + "smd/tlsph/strain/rate", + "wall/piston", + "spin", + "gayberne/gpu", + "smd/tlsph", + "slice", + "born/coul/wolf/omp", + "cosine/squared", + "lj/cut/coul/msm/dielectric", + "create_elementset", + "agni", + "dpd/fdt/energy", + "property/molecule", + "dihedral", + "ke", + "nm/cut/coul/cut/omp", + "lj/sf/dipole/sf/gpu", + "lj/cut/coul/dsf/kk", + "coul/debye/gpu", + "min_style cg", + "gyration/shape", + "time_integration", + "dpd/atom", + "tersoff/omp", + "gw", + "improper_style", + "plane", + "lj/cut/soft/omp", + "set", + "lj/cut/tip4p/long/soft/omp", + "mask_direction", + "coul/dsf/kk", + "exchange", + "temp/asphere", + "lj/cut/coul/long/gpu", + "born", + "fix_flux", + "lj/charmm/coul/long/intel", + "spin/dmi", + "box/relax", + "elif", + "charmm", + "ufm", + "class2", + "quartic/omp", + "box", + "info", + "gyration", + "couple/cfd", + "spring/chunk", + "tip4p/cut/omp", + "sna/atom", + "undump", + "nve", + "lattice", + "qeq/reaxff", + "qtb", + "wall/reflect/stochastic", + "gyration/molecule", + "buck/coul/long", + "nparticles/tracer/region", + "fourier", + "timer", + "gran/hertz/history", + "smd/wall_surface", + "soft", + "lj/spica/coul/long", + "cvff/omp", + "com/molecule", + "angle_coeff", + "lubricate/poly", + "lj/cut/tip4p/long", + "lj/charmm/coul/charmm/implicit/kk", + "lj/cut/coul/long", + "spin/neel", + "msd/nongauss", + "charmm/omp", + "INF", + "oxrna2/stk", + "massflow/mesh", + "reduce/region", + "lj/cut/coul/debye/dielectric", + "lj/class2/coul/cut", + "npt/asphere/omp", + "create_atoms", + "comb", + "bond/create", + "langevin/spin", + "hyper/global", + "lj/expand/kk", + "boundary_dynamics", + "lj/cut/tip4p/cut", + "package", + "bpm/rotational", + "third_order", + "lj/expand/coul/long/gpu", + "coul/long/kk", + "lj/smooth/omp", + "write", + "buck/mdf", + "coul/dsf", + "coord/atom/kk", + "property/atom/tracer", + "eos/table/rx", + "ave/sphere/atom", + "communicate", + "nodeset", + "comb3", + "dihedral_style", + "buck/coul/long/omp", + "coord/gran", + "sph/pressure", + "acks2/reaxff/kk", + "tfmc", + "electron/stopping", + "extep", + "rigid/small/omp", + "xrd", + "orientorder/atom/kk", + "dpd/energy/kk", + "add_molecule", + "spin/magelec", + "distharm", + "stress/atom", + "rigid/nph/omp", + "cosine/shift/exp", + "qeq/shielded", + "rigid/omp", + "dpd/omp", + "log", + "cosine/delta/omp", + "property/local", + "ke/rigid", + "acks2/reaxff", + "shell", + "hyper", + "reduce", + "coul/exclude", + "centro/atom", + "eam/alloy/intel", + "yukawa/omp", + "no", + "dipole/chunk", + "next", + "fene/omp", + "coul/cut/gpu", + "temp/profile", + "zbl/omp", + "remove_source", + "reset_mol_ids", + "adp/omp", + "ptm/atom", + "rattle", + "fourier/simple", + "cvff/intel", + "coul/debye/kk", + "sw/gpu", + "none", + "ave/correlate/long", + "inertia/chunk", + "born/gpu", + "lj/sf/dipole/sf", + "npt/cauchy", + "tmd", + "lj/cut/dipole/long/gpu", + "drude/transform/direct", + "oxrna2/coaxstk", + "nvt/asphere/omp", + "ufm/omp", + "heat/flux/tally", + "oxdna/excv", + "ufm/opt", + "gran/hooke/history/omp", + "nonlinear", + "lj/spica/gpu", + "vashishta/omp", + "npt/gpu", + "atm", + "smd/tlsph/dt", + "edpd/source", + "numdiff", + "thermo_style", + "lj/cubic/omp", + "recenter", + "table/kk", + "brownian/sphere", + "multicontact/halfspace", + "lj/charmm/coul/msm/omp", + "lb/fluid", + "thermal/conductivity", + "coord/atom", + "tri/lj", + "eos/table", + "processors", + "scale", + "lj/cut/omp", + "adp", + "nharmonic/omp", + "nvt/sllod/eff", + "oxdna2/coaxstk", + "ackland/atom", + "lj/gromacs/kk", + "nvt/eff", + "erotate/rigid", + "mesont", + "born/coul/msm/omp", + "labelmap", + "born/coul/long/omp", + "gran/hertz/history/omp", + "tersoff/kk", + "create_nodeset", + "decomposition", + "bop", + "reduce/chunk", + "sw/kk", + "property/atom/regiontracer/time", + "temp/region", + "reset_atomic_reference_positions", + "lj96/cut/omp", + "buck/coul/long/gpu", + "quadratic/omp", + "resquared/gpu", + "dt/reset", + "atom_weight", + "nvk", + "nve/limit", + "unfix_flux", + "ufm/gpu", + "fourier/omp", + "comm_style", + "rigid/nvt", + "chunk/atom", + "vashishta/table", + "nph/sphere", + "sph/t/atom", + "mscg", + "filter/corotate", + "temper/grem", + "min_style hftn", + "npt/kk", + "dpd/tstat/omp", + "dilatation/atom", + "buck6d/coul/gauss/dsf", + "mesh/surface/planar", + "langevin/drude", + "fourier/simple/omp", + "lj/smooth/linear/omp", + "dpd/tstat/gpu", + "nm/cut/omp", + "pair_interactions", + "lj/cut/tip4p/long/opt", + "netcdf", + "remove_species", + "eos/table/rx/kk", + "smatb", + "table/rx/kk", + "neighbor_skin", + "ilp/tmd", + "hma", + "buck/coul/cut/kk", + "buck/kk", + "ave/time", + "quit", + "gran/hooke/history/kk", + "harmonic/shift/cut", + "coul/wolf/cs", + "thermo_modify", + "coul/debye", + "tersoff/zbl/kk", + "gyration/chunk", + "lj/class2/coul/cut/omp", + "particletemplate/multisphere", + "oxdna/stk", + "rerun", + "fix", + "rigid/nvt/small", + "viscous", + "atom_element_map", + "temp/kk", + "born/coul/long", + "wall/gran", + "wall/region/sph", + "pe/mol/tally", + "wall/lj126", + "charmm/intel", + "temp/berendsen", + "else", + "gayberne/intel", + "false", + "oxrna2/xstk", + "wall/colloid", + "improper/local", + "npt/sphere", + "internal_quadrature", + "nve/eff", + "gromos", + ], - typeKeywords: [], + typeKeywords: [], - operators: [ - "=", - ">", - "<", - "!", - "~", - "?", - ":", - "==", - "<=", - ">=", - "!=", - "&&", - "||", - "++", - "--", - "+", - "-", - "*", - "/", - "&", - "|", - "^", - "%", - "<<", - ">>", - ">>>", - "+=", - "-=", - "*=", - "/=", - "&=", - "|=", - "^=", - "%=", - "<<=", - ">>=", - ">>>=", - ], + operators: [ + "=", + ">", + "<", + "!", + "~", + "?", + ":", + "==", + "<=", + ">=", + "!=", + "&&", + "||", + "++", + "--", + "+", + "-", + "*", + "/", + "&", + "|", + "^", + "%", + "<<", + ">>", + ">>>", + "+=", + "-=", + "*=", + "/=", + "&=", + "|=", + "^=", + "%=", + "<<=", + ">>=", + ">>>=", + ], - // we include these common regular expressions - symbols: /[=>](?!@symbols)/, "@brackets"], - [/@symbols/, { cases: { "@operators": "operator", "@default": "" } }], + // delimiters and operators + [/[{}()[\]]/, "@brackets"], + [/[<>](?!@symbols)/, "@brackets"], + [/@symbols/, { cases: { "@operators": "operator", "@default": "" } }], - // @ annotations. - // As an example, we emit a debugging log message on these tokens. - // Note: message are supressed during the first load -- change some lines to see them. + // @ annotations. + // As an example, we emit a debugging log message on these tokens. + // Note: message are supressed during the first load -- change some lines to see them. - // numbers - [/\d*\.\d+([eE][-+]?\d+)?/, "number.float"], - [/0[xX][0-9a-fA-F]+/, "number.hex"], - [/\d+/, "number"], + // numbers + [/\d*\.\d+([eE][-+]?\d+)?/, "number.float"], + [/0[xX][0-9a-fA-F]+/, "number.hex"], + [/\d+/, "number"], - // delimiter: after number because of .\d floats - [/[;,.]/, "delimiter"], + // delimiter: after number because of .\d floats + [/[;,.]/, "delimiter"], - // strings - [/"([^"\\]|\\.)*$/, "string.invalid"], // non-teminated string - [/"/, { token: "string.quote", bracket: "@open", next: "@string" }], + // strings + [/"([^"\\]|\\.)*$/, "string.invalid"], // non-teminated string + [/"/, { token: "string.quote", bracket: "@open", next: "@string" }], - // characters - [/'[^\\']'/, "string"], - [/(')(@escapes)(')/, ["string", "string.escape", "string"]], - [/'/, "string.invalid"], - ], + // characters + [/'[^\\']'/, "string"], + [/(')(@escapes)(')/, ["string", "string.escape", "string"]], + [/'/, "string.invalid"], + ], - comment: [ - [/[^/*]+/, "comment"], - [/\/\*/, "comment", "@push"], // nested comment - ["\\*/", "comment", "@pop"], - [/[/*]/, "comment"], - [/^#/, "comment"], - ], + comment: [ + [/[^/*]+/, "comment"], + [/\/\*/, "comment", "@push"], // nested comment + ["\\*/", "comment", "@pop"], + [/[/*]/, "comment"], + [/^#/, "comment"], + ], - string: [ - [/[^\\"]+/, "string"], - [/@escapes/, "string.escape"], - [/\\./, "string.escape.invalid"], - [/"/, { token: "string.quote", bracket: "@close", next: "@pop" }], - ], + string: [ + [/[^\\"]+/, "string"], + [/@escapes/, "string.escape"], + [/\\./, "string.escape.invalid"], + [/"/, { token: "string.quote", bracket: "@close", next: "@pop" }], + ], - whitespace: [ - [/[ \t\r\n]+/, "white"], - [/\/\*/, "comment", "@comment"], - [/\/\/.*$/, "comment"], - ], - }, + whitespace: [ + [/[ \t\r\n]+/, "white"], + [/\/\*/, "comment", "@comment"], + [/\/\/.*$/, "comment"], + ], + }, }); }); @@ -1419,24 +1418,19 @@ const Edit = () => { selectOnLineNumbers: true, }; - const handleEditorDidMount = useCallback( - (editor: Monaco.editor.IStandaloneCodeEditor) => { - editor.focus(); - }, - [], - ); + const handleEditorDidMount = useCallback((editor: Monaco.editor.IStandaloneCodeEditor) => { + editor.focus(); + }, []); const onEditorChange = useCallback( (newValue: string | undefined) => { if (!newValue) return; - const file = simulation?.files.find( - (file) => file.fileName === selectedFile?.fileName, - ); + const file = simulation?.files.find((file) => file.fileName === selectedFile?.fileName); if (file) { file.content = newValue; } }, - [selectedFile?.fileName, simulation?.files], + [selectedFile?.fileName, simulation?.files] ); if (!selectedFile) { diff --git a/src/containers/Examples.css b/src/containers/Examples.css index a178e6f7..918035b6 100644 --- a/src/containers/Examples.css +++ b/src/containers/Examples.css @@ -2,9 +2,14 @@ .modern-card { border-radius: 16px; overflow: hidden; - transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease; + transition: + transform 0.3s ease, + box-shadow 0.3s ease, + border-color 0.3s ease; border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.2), 0 8px 32px rgba(0, 0, 0, 0.1); + box-shadow: + inset 0 0 20px rgba(0, 0, 0, 0.2), + 0 8px 32px rgba(0, 0, 0, 0.1); background: rgba(42, 41, 47, 0.6); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); @@ -20,11 +25,7 @@ left: 0; width: 100%; height: 100%; - background: linear-gradient( - to bottom, - rgba(255, 255, 255, 0.15) 0%, - transparent 50% - ); + background: linear-gradient(to bottom, rgba(255, 255, 255, 0.15) 0%, transparent 50%); pointer-events: none; opacity: 0.5; z-index: 1; @@ -34,7 +35,9 @@ .modern-card:hover { transform: translateY(-4px); - box-shadow: inset 0 0 30px rgba(0, 0, 0, 0.3), 0 12px 40px rgba(0, 0, 0, 0.2); + box-shadow: + inset 0 0 30px rgba(0, 0, 0, 0.3), + 0 12px 40px rgba(0, 0, 0, 0.2); border-color: rgba(255, 255, 255, 0.2); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); @@ -220,7 +223,7 @@ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; } - + .card-image { height: 160px; } diff --git a/src/containers/Examples.tsx b/src/containers/Examples.tsx index 6096bffe..24baf846 100644 --- a/src/containers/Examples.tsx +++ b/src/containers/Examples.tsx @@ -1,15 +1,14 @@ -import { useCallback, useState, useEffect } from "react"; -import { Select, Divider } from "antd"; -import { Simulation } from "../store/simulation"; -import { SimulationFile } from "../store/app"; -import { useStoreActions, useStoreState } from "../hooks"; import { CaretRightOutlined, EditOutlined } from "@ant-design/icons"; -import { Layout, Skeleton, notification } from "antd"; -import { track } from "../utils/metrics"; +import { Divider, Layout, notification, Select, Skeleton } from "antd"; +import { useCallback, useEffect, useState } from "react"; import ReactMarkdown from "react-markdown"; -import remarkMath from "remark-math"; -import rehypeKatex from "rehype-katex"; import rehypeExternalLinks from "rehype-external-links"; +import rehypeKatex from "rehype-katex"; +import remarkMath from "remark-math"; +import { useStoreActions, useStoreState } from "../hooks"; +import type { SimulationFile } from "../store/app"; +import type { Simulation } from "../store/simulation"; +import { track } from "../utils/metrics"; import "katex/dist/katex.min.css"; import "./Examples.css"; @@ -36,29 +35,25 @@ const Examples = () => { const [examples, setExamples] = useState([]); const [filterKeywords, setFilterKeywords] = useState([]); // Width measurement no longer needed with CSS Grid - const setNewSimulation = useStoreActions( - (actions) => actions.simulation.newSimulation, - ); + const setNewSimulation = useStoreActions((actions) => actions.simulation.newSimulation); const simulation = useStoreState((state) => state.simulation.simulation); const running = useStoreState((state) => state.simulation.running); - const setPreferredView = useStoreActions( - (actions) => actions.app.setPreferredView, - ); + const setPreferredView = useStoreActions((actions) => actions.app.setPreferredView); useEffect(() => { const fetchExamples = async (examplesUrl: string) => { let response = await fetch(examplesUrl, { cache: "no-store" }); const data = await response.json(); - const baseUrl = data["baseUrl"]; - const title = data["title"] || "Examples"; - const descriptionsUrl = `${baseUrl}/${data["descriptionFile"]}`; + const baseUrl = data.baseUrl; + const title = data.title || "Examples"; + const descriptionsUrl = `${baseUrl}/${data.descriptionFile}`; response = await fetch(descriptionsUrl); if (response.status !== 404) { const description = await response.text(); setDescription(description); } - const examples: Example[] = data["examples"]; + const examples: Example[] = data.examples; examples.forEach((example) => { example.imageUrl = `${baseUrl}/${example.imageUrl}`; example.files.forEach((file) => { @@ -67,7 +62,7 @@ const Examples = () => { }); setTitle(title); - setExamples(data["examples"]); + setExamples(data.examples); track("Examples.Fetch", { examplesUrl }); }; @@ -75,15 +70,15 @@ const Examples = () => { const urlSearchParams = new URLSearchParams(window.location.search); const params = Object.fromEntries(urlSearchParams.entries()); - let defaultExamplesUrl = "examples/examples.json"; + const defaultExamplesUrl = "examples/examples.json"; let examplesUrl = defaultExamplesUrl; - if (params["examplesUrl"] != null) { - examplesUrl = params["examplesUrl"]; + if (params.examplesUrl != null) { + examplesUrl = params.examplesUrl; } try { await fetchExamples(examplesUrl); - } catch (e) { + } catch (_e) { notification.error({ message: `Could not fetch examples from ${examplesUrl}. Fetching default.`, }); @@ -106,15 +101,14 @@ const Examples = () => { if (running) { notification.info({ message: "Simulation already running", - description: - "You can't start a new simulation while another one is running.", + description: "You can't start a new simulation while another one is running.", }); } else { setNewSimulation(newSimulation); setPreferredView("view"); } }, - [running, setNewSimulation, setPreferredView], + [running, setNewSimulation, setPreferredView] ); const onEdit = useCallback( @@ -129,35 +123,43 @@ const Examples = () => { if (simulation?.id !== newSimulation.id) { setNewSimulation(newSimulation); } else { - setPreferredView("file" + newSimulation.inputScript); + setPreferredView(`file${newSimulation.inputScript}`); } }, - [setNewSimulation, setPreferredView, simulation?.id], + [setNewSimulation, setPreferredView, simulation?.id] ); - let keywordsSet: Set = new Set(); + const keywordsSet: Set = new Set(); examples.forEach((example) => { if (example.keywords) { - example.keywords.forEach((keyword) => keywordsSet.add(keyword)); + example.keywords.forEach((keyword) => { + keywordsSet.add(keyword); + }); } }); const keywords = Array.from(keywordsSet); keywords.sort(); const renderCard = (example: Example) => ( -
onPlay(example)} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + onPlay(example); + } + }} >
- {example.title} + {example.title}
- -
-
{example.title}
-
{example.description}
+
+ {example.title} +
+
+ {example.description} +
{example.author && ( diff --git a/src/containers/Main.tsx b/src/containers/Main.tsx index da93d355..ecacbb55 100644 --- a/src/containers/Main.tsx +++ b/src/containers/Main.tsx @@ -1,13 +1,14 @@ -import { Modal, Tabs, Progress, Button, Layout } from "antd"; -import { useState, useEffect, useMemo } from "react"; -import View from "./View"; -import Notebook from "./Notebook"; -import Edit from "./Edit"; +import { Button, Layout, Modal, Progress, Tabs } from "antd"; +import { useEffect, useMemo, useState } from "react"; +import LoadingSimulationScreen from "../components/LoadingSimulationScreen"; +import { useStoreActions, useStoreState } from "../hooks"; import Console from "./Console"; +import Edit from "./Edit"; import Examples from "./Examples"; +import Notebook from "./Notebook"; import RunInCloud from "./RunInCloud"; -import LoadingSimulationScreen from "../components/LoadingSimulationScreen"; -import { useStoreActions, useStoreState } from "../hooks"; +import View from "./View"; + const { Content } = Layout; const Main = ({ isEmbedded }: { isEmbedded: boolean }) => { @@ -15,17 +16,13 @@ const Main = ({ isEmbedded }: { isEmbedded: boolean }) => { const showConsole = useStoreState((state) => state.simulation.showConsole); const [consoleKey, setConsoleKey] = useState(0); const [hasStarted, setHasStarted] = useState(false); - const setShowConsole = useStoreActions( - (actions) => actions.simulation.setShowConsole, - ); + const setShowConsole = useStoreActions((actions) => actions.simulation.setShowConsole); const selectedMenu = useStoreState((state) => state.app.selectedMenu); const running = useStoreState((state) => state.simulation.running); - const setPreferredView = useStoreActions( - (actions) => actions.app.setPreferredView, - ); + const setPreferredView = useStoreActions((actions) => actions.app.setPreferredView); const status = useStoreState((state) => state.app.status); - + // Update console key when modal opens useEffect(() => { if (showConsole) { @@ -46,11 +43,12 @@ const Main = ({ isEmbedded }: { isEmbedded: boolean }) => { { key: "view", label: "View", - children: isEmbedded && !hasStarted ? ( - - ) : ( - - ), + children: + isEmbedded && !hasStarted ? ( + + ) : ( + + ), }, { key: "console", @@ -80,9 +78,7 @@ const Main = ({ isEmbedded }: { isEmbedded: boolean }) => { ]; // Filter out Examples tab in embedded mode - return isEmbedded - ? allTabs.filter(tab => tab.key !== "examples") - : allTabs; + return isEmbedded ? allTabs.filter((tab) => tab.key !== "examples") : allTabs; }, [isEmbedded, selectedMenu, hasStarted, status, wasm]); return ( diff --git a/src/containers/NewSimulation.tsx b/src/containers/NewSimulation.tsx index 1724975f..cd95d102 100644 --- a/src/containers/NewSimulation.tsx +++ b/src/containers/NewSimulation.tsx @@ -1,21 +1,11 @@ import { InboxOutlined } from "@ant-design/icons"; +import type { UploadFile, UploadProps } from "antd"; +import { Button, Checkbox, Divider, Input, Modal, message, Select, Tooltip, Upload } from "antd"; +import type { UploadChangeParam } from "antd/es/upload"; import { useCallback, useEffect, useState } from "react"; import { useStoreActions } from "../hooks"; -import { - message, - Upload, - Modal, - Button, - Select, - Divider, - Tooltip, - Input, - Checkbox, -} from "antd"; -import type { UploadProps, UploadFile } from "antd"; -import type { UploadChangeParam } from "antd/es/upload"; -import { Simulation } from "../store/simulation"; -import { SimulationFile } from "../store/app"; +import type { SimulationFile } from "../store/app"; +import type { Simulation } from "../store/simulation"; import { track } from "../utils/metrics"; const { Option } = Select; @@ -31,12 +21,8 @@ const NewSimulation = ({ onClose }: NewSimulationProps) => { const [files, setFiles] = useState([]); const [startImmediately, setStartImmediately] = useState(false); const [inputScript, setInputScript] = useState(); - const setNewSimulation = useStoreActions( - (actions) => actions.simulation.newSimulation, - ); - const setPreferredView = useStoreActions( - (actions) => actions.app.setPreferredView, - ); + const setNewSimulation = useStoreActions((actions) => actions.simulation.newSimulation); + const setPreferredView = useStoreActions((actions) => actions.app.setPreferredView); const validSimulation = name != null && @@ -52,9 +38,7 @@ const NewSimulation = ({ onClose }: NewSimulationProps) => { async (info: UploadChangeParam) => { // Need to use window.files because these async functions can't seem to agree on the state if (info.file.status === "removed") { - const newFiles = files.filter( - (file) => file.fileName !== info.file.name, - ); + const newFiles = files.filter((file) => file.fileName !== info.file.name); window.files = newFiles; setFiles(newFiles); return; @@ -72,7 +56,7 @@ const NewSimulation = ({ onClose }: NewSimulationProps) => { setFiles(window.files); message.success(`${file.fileName} uploaded successfully.`); }, - [files, setFiles], + [files] ); const props: UploadProps = { @@ -105,15 +89,7 @@ const NewSimulation = ({ onClose }: NewSimulationProps) => { setPreferredView("view"); } onClose(); - }, [ - files, - inputScript, - name, - onClose, - startImmediately, - setPreferredView, - setNewSimulation, - ]); + }, [files, inputScript, name, onClose, startImmediately, setPreferredView, setNewSimulation]); return ( {

Name

- setName(e.target.value)} - placeholder="Simulation name" - > + setName(e.target.value)} placeholder="Simulation name">

Files @@ -162,12 +135,10 @@ const NewSimulation = ({ onClose }: NewSimulationProps) => {

-

- Click or drag file to this area to upload -

+

Click or drag file to this area to upload

- Upload the files you need for your simulation. Note that these files - are not stored across Atomify sessions yet. + Upload the files you need for your simulation. Note that these files are not stored across + Atomify sessions yet.

{files.length > 0 && ( @@ -176,12 +147,11 @@ const NewSimulation = ({ onClose }: NewSimulationProps) => {

Select input script

- setInputScript(value)}> {files.map((file) => ( - + ))} diff --git a/src/containers/Notebook.tsx b/src/containers/Notebook.tsx index 4dfe95d1..d949d358 100644 --- a/src/containers/Notebook.tsx +++ b/src/containers/Notebook.tsx @@ -1,7 +1,7 @@ +import localforage from "localforage"; +import { useEffect, useState } from "react"; import Iframe from "react-iframe"; import { useStoreState } from "../hooks"; -import { useEffect, useState } from "react"; -import localforage from "localforage"; const Notebook = () => { const simulation = useStoreState((state) => state.simulation.simulation); @@ -15,7 +15,9 @@ const Notebook = () => { let path = "analyze.ipynb"; if (simulation?.analysisScript) { - const scriptName = simulation.analysisScript.substring(simulation.analysisScript.lastIndexOf('/') + 1); + const scriptName = simulation.analysisScript.substring( + simulation.analysisScript.lastIndexOf("/") + 1 + ); path = `${simulation.id}/${scriptName}`; } @@ -40,19 +42,17 @@ const Notebook = () => { }, [simulation]); return ( - <> -
-