<![CDATA[3 States of Matter (Solid, Liquid and Gas) Designed for G1]]> false false true true false ]]> ./Screenshot 2024-08-07 at 2.32.08 PM.png ./MolecularDynamicsExploration/wc_icon.png;./MolecularDynamicsExploration/dan.s_icon.png DESCRIPTION_EDITOR Molecular Dynamics Simulatation true true _default_ Molecular Dynamics Simulatation false

Molecular Dynamics Exploration

The Molecular Dynamics Explorataion was developed by Wolfgang Christian at Davidson College using the Easy Java/JavaScript Simulalation modeling and authoring tool created by Francisco Esquembre. This simulation is based on a pure JavaScript + HTML 5 simulation developed by Daniel V. Schroeder, Physics Department, Weber State University.

]]>
4 1 false VARIABLE_EDITOR Drawing Vars true false VARIABLE_EDITOR Particle Vars true false VARIABLE_EDITOR Constants true false CODE_EDITOR Init Atoms true false (Math.random() - 0.5) * 2); vy = new Array(y.length).fill(0).map(() => (Math.random() - 0.5) * 2); // Assigning to the data array let data = []; for (let i = 0; i < x.length; i++) { data.push(x[i], y[i], vx[i], vy[i]); } */ /* var neighborSpace = 1.5; // initial distance between molecules var nextX = neighborSpace/2; var nextY = neighborSpace/2; for (var i=0; i boxWidth -neighborSpace/2) { nextX = neighborSpace/2; nextY += neighborSpace; } } */ time = 0.0; totalT = 0.0; totalP = 0.0; stepCount=sampleCount = 0; startTime = (new Date()).getTime(); computeAccelerations(); window.setTimeout(drawAtoms, 100); ]]> CODE_EDITOR Read Presets true false CODE_EDITOR ComPADRE true false EVOLUTION_EDITOR Evol Page true false 0)? opts[0]:""; // selected option if ( option=="Solid"){ speedFactor(0.1); } ]]> CODE_EDITOR Update State Vars true false LIBRARY_EDITOR Compute Accelerations true false (boxWidth - 0.5)) { ax[i] = wallStiffness * (boxWidth - 0.5 - x[i]); wallForce -= ax[i]; potentialE += 0.5 * wallStiffness * (boxWidth-0.5-x[i]) * (boxWidth-0.5-x[i]); } else ax[i] = 0.0; if (y[i] < 0.5) { ay[i] = (wallStiffness * (0.5 - y[i])); wallForce += ay[i]; potentialE += 0.5 * wallStiffness * (0.5-y[i]) * (0.5-y[i]); } else if (y[i] > (boxWidth - 0.5)) { ay[i] = (wallStiffness * (boxWidth - 0.5 - y[i])); wallForce -= ay[i]; potentialE += 0.5 * wallStiffness * (boxWidth-0.5-y[i]) * (boxWidth-0.5-y[i]); } else ay[i] = 0; ay[i] -= g; // add gravity if any } pressure = wallForce / (4*boxWidth); // instantaneous pressure // now compute interaction forces (Lennard-Jones potential): // (this is where we spend most of our computation time, so try to optimize) if ((N < 100) || (boxWidth < 4*forceCutoff) /* || !cellListCheck.checked */ ) { for (var i=0; i= nCells) xCell = nCells - 1; yCell = Math.floor(y[i] / cellWidth); if (yCell < 0) yCell = 0; if (yCell >= nCells) yCell = nCells - 1; var cellHeaderIndex = xCell + nCells*yCell; // flatten 2D structure into 1D array linkedList[i] = listHeader[cellHeaderIndex]; // this atom now points where the header used to listHeader[cellHeaderIndex] = i; // header now points to his atom } // linked list is now complete for (xCell=0; xCell= nCells)) continue; // some neighbors don't actually exist yNeighborCell = yCell + neighborOffset[neighborIndex].y; if (yNeighborCell >= nCells) continue; neighborCell = xNeighborCell + nCells*yNeighborCell; // index of neighbor cell in header list var i = listHeader[thisCell]; while (i > -1) { // loop over atoms in this cell var j = listHeader[neighborCell]; if (neighborCell == thisCell) j = linkedList[i]; // be sure not to count atoms in this cell twice while (j > -1) { // loop over atoms in neighbor cell dx = x[i] - x[j]; dx2 = dx * dx; if (dx2 < forceCutoff2) { // make sure they're close enough to bother dy = y[i] - y[j]; dy2 = dy * dy; if (dy2 < forceCutoff2) { rSquared = dx2 + dy2; if (rSquared < forceCutoff2) { rSquaredInv = 1.0 / rSquared; attract = rSquaredInv * rSquaredInv * rSquaredInv; repel = attract * attract; potentialE += (4.0 * (repel - attract)) - pEatCutoff; //fOverR = 24.0 * ((2.0 * repel) - attract) * rSquaredInv; fOverR = 1.0 * ((2.0 * repel) - attract) * rSquaredInv; fx = fOverR * dx; fy = fOverR * dy; ax[i] += fx; // add this force on to i's acceleration (m = 1) ay[i] += fy; ax[j] -= fx; // Newton's 3rd law ay[j] -= fy; } } } j = linkedList[j]; } // end of loop over j i = linkedList[i]; } // end of loop over i } // end of loop over neighborIndex } // end of loop over yCell } // end of loop over xCell } // end if (and end of L-J force computation) // add elastic forces between bonded atoms: //var bondStrength = 100; // spring constant (vastly less than actual covalent bonds!) var bondStrength = 100; for (var i=0; i LIBRARY_EDITOR Utility Func true false boxWidth -neighborSpace/2) { nextX = neighborSpace/2; nextY += neighborSpace; if(nextY>boxWidth-neighborSpace/2) break; } } return maxN; } //change all speeds by a given factor (called by button presses): function speedFactor(factor) { for (var i=0; i LIBRARY_EDITOR Mouse Actions true false LIBRARY_EDITOR Draw true false speedLimit) { atomColor[i]= lastColor; } else { atomColor[i] = speedColorList[Math.floor(speed*speedColorList.length/speedLimit)]; } } } function drawAtoms () { setColors(); var context = _view.canvas.getContext('2d'); context.fillStyle='Black'; context.fillRect(0,0,width,height); for(var i=0; i
"+ "x = " + Number(x[selectedAtom]).toExponential(3) + "
" + "y = " + Number(y[selectedAtom]).toExponential(3) + "
" + "vx= " + Number(vx[selectedAtom]).toExponential(3) + "
" + "vy= " + Number(vy[selectedAtom]).toExponential(3); } } ]]>
LIBRARY_EDITOR Simulate true false LIBRARY_EDITOR Do Step true false = 1.0); var u = Math.sqrt(-2*Math.log(w)/w); // polar Box-Muller transformation to get Gaussian distribution vx[fixedTList[i].pointer] = u * x1 * Math.sqrt(fixedTList[i].temp); vy[fixedTList[i].pointer] = u * x2 * Math.sqrt(fixedTList[i].temp); } } time += dt; } // Compute statistical data from current system state: function computeStats() { kineticE = 0; gravitationalE = 0; momentumX = 0; momentumY = 0; for (var i=0; i 1000) { // handle run-away instability if (T > 10) { // handle run-away instability var alertString = "Oops! The simulation has become unstable.\n"; alertString += "Avoid placing atoms so they overlap and use a smaller time step if high temperatures are expected.\n"; alertString += "Click OK and reset the initial conditions."; if(isRunning)window.setTimeout(alert(alertString), 50); isRunning=false; _pause(); } else { var safetyFactor = 4000; if ((T > 1/(safetyFactor*dt*dt)) && (dtAdapt)) { dt = Math.max(Math.sqrt(1/(safetyFactor*T)) - 0.001, 0.001); } if ((T < 0.5/(safetyFactor*dt*dt)) && (dtAdapt)) { dt = Math.min(Math.sqrt(0.5/(safetyFactor*T)) + 0.001, 0.05); } } } // Periodically update the temperature and pressure accumulators function updateTandP() { sampleCount++; kineticE = 0; for (var i=0; i LIBRARY_EDITOR Load Presets true false = N) { selectedAtom = -1; } computeAccelerations(); resetTime(); drawAtoms (); } ]]>
HTML_VIEW_EDITOR HtmlView true false 0 0 0 800 600 true true Elements.WrappedPanel true Elements.Panel Elements.Label Molecular Dynamics Exploration"]]> true Elements.Panel Elements.ComboBox Elements.TwoStateButton Elements.Button true Elements.Panel Elements.Label Elements.ParsedField false Elements.Panel Elements.Label Elements.ParsedField false Elements.Panel Elements.Label Elements.ParsedField true Elements.Panel Elements.Canvas false Elements.Panel Elements.Panel true Elements.Panel false Elements.Panel false Elements.Panel Elements.Label Elements.ParsedField false Elements.Panel Elements.Label Elements.ParsedField false Elements.Panel Elements.Label Elements.ParsedField Elements.Button Elements.TwoStateButton true Elements.Panel false Elements.Panel Elements.Label Elements.ParsedField false Elements.Panel Elements.Label Elements.ParsedField false Elements.Panel Elements.Label Elements.ParsedField false Elements.Panel Elements.Label Elements.ParsedField true Elements.Panel Elements.Label Elements.ParsedField Elements.CheckBox true Elements.Panel Elements.TwoStateButton Elements.Button Elements.Button Elements.Button Elements.Button Elements.Button Elements.Button Elements.Button Elements.Panel The Molecular Dynamics Exploration shows the molecular dynamics of simple atoms and molecules in a two-dimensional system. The force between the atoms is weakly attractive at short distances, but strongly repulsive when they touch. Use the simulation to explore phases of matter, emergent behavior, irreversibility, and thermal effects at the nanoscale.

The physics

  • Each atom in the simulation moves in response to the forces exerted by nearby atoms and the container walls, in accord with Newton’s laws of motion. The simulation code knows nothing about phase transformations or crystal structure or irreversibility, yet these high-level phenomena, and others, emerge from the microscopic physics.
  • The force between the atoms is calculated from the Lennard-Jones formula (truncated at a distance of 3 molecular diameters). This is a reasonably accurate model of the interactions between noble gas atoms.
  • The simulation approximates Newton’s laws using the Verlet algorithm with the indicated Time step Δt. Using too large a time step can make the simulation inaccurate and sometimes even unstable (see below).
  • The simulation uses a natural system of units, with the atomic diameter, the atomic mass, the depth of the Lennard-Jones potential, and Boltzmann’s constant all set equal to 1. For argon (for example), the unit of distance is 3.4 angstroms, the unit of mass is 40 atomic mass units, and the unit of energy is 0.012 electron-volts; the corresponding unit of time is then 2 picoseconds, the unit of velocity is 170 meters per second, and the unit of temperature is 140 kelvin.
  • The walls exert a linear (spring) force on the molecules, with a spring constant of 50 in natural units.
  • There’s an optional uniform downward force, controlled by the gravity parameter g that is available using the More button. The magnitude of this force, however, is not meant to be realistic. The numerical value should be small to avoid numerical instabiity. A value of g ~0.01 gives a good visualization with the default initialialization but it is orders of magnitude larger than 9.8 m/s2. Earth’s gravitational constant is utterly negligible in the units used here (a little over 10−13 for argon).

Credits

The Molecular Dynamics Exploration was developed by Wolfgang Christian at Davidson College using the Easy Java/JavaScript Simulation (EjsS) modeling and authoring tool created by Francisco Esquembre. This EjsS simulation is based on a pure JavaScript + HTML 5 simulation developed by Daniel V. Schroeder, Physics Department, Weber State University. Schroeder's simulation is described in Interactive Molecular Dynamics article (pdf), published in the American Journal of Physics 83 (3), 210-218 (2015), arXiv:1502.06169 [physics.ed-ph].

]]>
Elements.Panel The user interface:
  • Press the Start button to start the simulation, or the Step button to step forward in time by a small amount. The Reset time button restarts with the current parameters and the Reset button starts with the default configuration.
  • The Faster and Slower buttons increase and decrease the speeds of all the atoms by 10%. Press them repeatedly for a greater effect. The Freeze button sets all the speeds to zero. Using these buttons puts the system out of thermal equilibrium; it’s fun to then watch it try to equilibrate.
  • Don’t expect the Reverse button to accurately run the motion backwards for long; the motion is almost always chaotic!
  • The Δt field sets the time step in the numerical algorithm. If the time step is too small the simulation becomes unstable, producing a runaway effect of exponentially increasing energy. This is a consequence of approximating the relations between position, velocity, and acceleration using small differences instead of derivatives. If the simulation becomes unstable, it will stop running and an alert box will appear. Do what it says and reduce the time step.
  • The Width input field changes the size of the container (in units of atomic diameters); since the container is always drawn to fill the same area on the screen, this setting also determines the scale (zoom level) of the image. This parameter and other parameters that fundamentally change the system, such as the number of atoms, can only be changed when the system is paused.
  • The statistics displayed below the image are total energy, temperature, and pressure. The temperature is computed from the average kinetic energy, so it isn’t accurate when there’s organized motion on a large scale. The temperature and pressure are averaged over time.
  • The simulation time and the numerical simulation steps per second are displayed in yellow message boxes in the drawing panel. The steps per second will depend on the processor speed. Typical values are a few thousand steps per second on modern quad-core desktop computers and hundreds of steps per second on tablets and other mobile devices.
  • Yes, you can drag the atoms around with the mouse or other pointing mechanism (at least on traditional computers and iOS touch-screen devices) when the simulation is paused. Note: Dragging may not work on some browsers until the simulaiton has executed at least one time step.
  • The atoms are colored by speed. The brightest color is used for all speeds greater than 3.0.

The More detail button displays additional data and options.

  • Instantaneous kinetic energy KE, potential energy PE, and gravitational potential energy GE are shown.
  • The Adapt check box will try to reduce the time step as needed to keep the calculation stable. Adapting the time step is not foolproof.
  • The Steps per frame (SPF) field controls the number of numerical computations in a time step. Decreasing this value will slow the simulation's display without affecting the numerical accuracy.

Additional features

Be sure to explore the Presets. (Thanks to John Mallinckrodt for inspiring several of the presets.) Many of these presets use features that are only available in the original simulation by Dan Schroeder. We have imported the configuration file generated with Schroeder's simulation into the EjsS model.

  • An atom can be anchored in space. Anchored atoms are drawn in light gray. You can drag an anchored atom when the simulaiton is paused.
  • Two atoms can be connected together with a “bond” that creates a spring-like force between them (in addition to the Lennard-Jones force). The spring constant is 100 in natural units, and the equilibrium position is the same as for the Lennard-Jones force. Although this feature allows some interesting qualitative demonstrations, it is not realistic: Actual covalent bonds are thousands of times stiffer. Bonds are drawn as thin gray lines.
  • Finally, atoms can have a“fixed temperature” of an atom, causing it to move randomly as if it is in contact with a heat bath at a specified temperature. The fixed-T atom will then be marked with a gray dot. (If the atom is part of a rigid solid, this feature has the side effect of exerting a drag force that impedes any macroscopic motion of the solid.)
]]>