Author Topic: Sodium Chloride  (Read 9727 times)

0 Members and 1 Guest are viewing this topic.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Sodium Chloride
« on: November 12, 2018, 08:06:29 am »
This is a model (sic!) of sodium and chlorine atoms (ions) forming a crystal from an initial random array of atoms (equal numbers).

In reality, the sodium chloride crystal is a face-centred cubic structure of ionic sodium and chlorine.  In the program, I have simulated forces as follows:

Force between sodium and chlorine is a combination of an attractive inverse-square force plus  a repulsive shorter-distance force.  The repulsive force is a very much simplified attempt at simulating the atomic structure quantum forces.  Thus, far away sodium and chlorine attract, but close up they repel.

Force between like atoms is always repulsive inverse-square.

The motion of the atoms is then determined by Newtonian mechanics (so you can appreciate how very simplified the model is!).

In the model, sodium are the smaller blue atoms and chlorine the larger red ones.  They are transparent so you can see the resulting structure in 3D.

In the model, the atoms have a maximum velocity (simulating thermal exchange to the lattice – again very simplified).

The 'atoms' do coalesce into a structure where the sodium atoms are distributed through the chlorine atoms and vice-versa: a 'crystalline structure' is indeed formed!  I don't know what type of structure it is (probably hexagonal close-packed?).  But it is, nevertheless, quite pleasing (the atoms oscillate in their crystal positions).  I may try and introduce more physically realistic forces in a future version.

Code: QB64: [Select]
  1. 'Simple Model of Ionic Crystal v1 by QWERKEY 2018-11-12
  2.  
  3. CONST A0! = 100, A1! = 2, R0! = 250, R1! = 2.3, A2! = 200, R2! = 115, FMin! = -5 '-55
  4. CONST NoBalls%% = 20
  5.  
  6. DIM BallStats%(1, 2), Cyperium&(1)
  7. DIM SHARED SodiumPos!(NoBalls%% - 1, 2), ChlorinePos!(NoBalls%% - 1, 2) 'Sodium 1, Chlorine 0
  8. DIM SHARED SodiumVel!(NoBalls%% - 1, 2), ChlorineVel!(NoBalls%% - 1, 2)
  9. DIM SodiumAcc!(NoBalls%% - 1, 2), ChlorineAcc!(NoBalls%% - 1, 2)
  10. CONST BallSize1%% = 79, BallSize0%% = 190, Offset% = 730, ScreenX% = 1260, ScreenY% = 800
  11.  
  12. _TITLE "Very Accurate Quantum Physics Model"
  13.  
  14. FOR N%% = 0 TO NoBalls%% - 1
  15.     FOR M%% = 0 TO 2
  16.         ChlorinePos!(N%%, M%%) = ScreenX% * (RND - 0.5) / 1.5
  17.         SodiumPos!(N%%, M%%) = ScreenX% * (RND - 0.5) / 1.5
  18.         ChlorineVel!(N%%, M%%) = (RND - 0.5) * 0.1
  19.         SodiumVel!(N%%, M%%) = (RND - 0.5) * 0.1
  20.     NEXT M%%
  21. NEXT N%%
  22.  
  23. ' Ball Colours (Cyperium Method)
  24. DATA 0,0,255
  25. DATA 255,0,0
  26. FOR N%% = 0 TO 1
  27.     FOR P%% = 0 TO 2
  28.         READ BallStats%(N%%, P%%)
  29.     NEXT P%%
  30.     TempImage& = _NEWIMAGE(256, 256, 32)
  31.     _DEST TempImage&
  32.     COLOR _RGBA(BallStats%(N%%, 0), BallStats%(N%%, 1), BallStats%(N%%, 2), 65), _RGBA(0, 0, 0, 0)
  33.     'Image data goes from 1 to 255 (not 0 to 255)
  34.     FOR Z% = 128 TO 255
  35.         FOR X% = 1 TO 255
  36.             FOR Y% = 1 TO 255
  37.                 DeltaX% = X% - 127
  38.                 DeltaY% = Y% - 127
  39.                 DeltaZ% = Z% - 127
  40.                 Dist! = SQR((DeltaX% * DeltaX%) + (DeltaY% * DeltaY%) + (DeltaZ% * DeltaZ%))
  41.                 IF Dist! > 125 AND Dist! < 127 THEN PSET (X%, Y%), _RGBA(CINT(Z% * BallStats%(N%%, 0) * (1 - (XBright! * X% / 255)) / 255), CINT(Z% * BallStats%(N%%, 1) * (1 - (XBright! * X% / 255)) / 255), CINT(Z% * BallStats%(N%%, 2) * (1 - (XBright! * X% / 255)) / 255), 65)
  42.             NEXT
  43.         NEXT
  44.     NEXT
  45.     Cyperium&(N%%) = _COPYIMAGE(TempImage&)
  46. NEXT N%%
  47.  
  48. Sodium& = _COPYIMAGE(Cyperium&(1), 33)
  49. _FREEIMAGE Cyperium&(1)
  50. Chlorine& = _COPYIMAGE(Cyperium&(0), 33)
  51. _FREEIMAGE Cyperium&(0)
  52.  
  53. 'Create screen
  54. SCREEN _NEWIMAGE(ScreenX%, ScreenY%, 32)
  55. _DISPLAYORDER _HARDWARE 'do not even render the software layer, just the hardware one.
  56.  
  57.     _LIMIT 30
  58.     CALL CentreOfMass
  59.     FOR N%% = 0 TO NoBalls%% - 1
  60.         _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Chlorine& TO(-(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), (BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)-((BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), (BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)-(-(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), -(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)
  61.         _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Chlorine& TO((BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), -(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)-(-(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), -(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)-((BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), (BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)
  62.         _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Sodium& TO(-(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), (BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)-((BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), (BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)-(-(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), -(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)
  63.         _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Sodium& TO((BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), -(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)-(-(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), -(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)-((BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), (BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)
  64.         FOR M%% = 0 TO 2
  65.             SodiumAcc!(N%%, M%%) = 0
  66.         NEXT M%%
  67.         FOR M%% = 0 TO 2
  68.             ChlorineAcc!(N%%, M%%) = 0
  69.         NEXT M%%
  70.         FOR L%% = 0 TO NoBalls%% - 1
  71.             'opposites
  72.             D! = SQR((SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)) * (SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)) + (SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)) * (SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)) + (SodiumPos!(N%%, 2) - ChlorinePos!(L%%, 2)) * (SodiumPos!(N%%, 2) - ChlorinePos!(L%%, 2)))
  73.             F! = (Attraction(D!) + Repulsion(D!)) / 1000
  74.             'IF F! < FMin! / 1000 THEN F! = FMin! / 1000
  75.             FOR M%% = 0 TO 2
  76.                 SodiumAcc!(N%%, M%%) = -F! * (SodiumPos!(N%%, M%%) - ChlorinePos!(L%%, M%%)) / D! + SodiumAcc!(N%%, M%%)
  77.             NEXT M%%
  78.             D! = SQR((SodiumPos!(L%%, 0) - ChlorinePos!(N%%, 0)) * (SodiumPos!(L%%, 0) - ChlorinePos!(N%%, 0)) + (SodiumPos!(L%%, 1) - ChlorinePos!(N%%, 1)) * (SodiumPos!(L%%, 1) - ChlorinePos!(N%%, 1)) + (SodiumPos!(L%%, 2) - ChlorinePos!(N%%, 2)) * (SodiumPos!(L%%, 2) - ChlorinePos!(N%%, 2)))
  79.             F! = (Attraction(D!) + Repulsion(D!)) / 1000
  80.             'IF F! < FMin! / 1000 THEN F! = FMin! / 1000
  81.             FOR M%% = 0 TO 2
  82.                 ChlorineAcc!(N%%, M%%) = F! * (SodiumPos!(L%%, M%%) - ChlorinePos!(N%%, M%%)) / D! + ChlorineAcc!(N%%, M%%)
  83.             NEXT M%%
  84.             IF L%% <> N%% THEN
  85.                 'same type
  86.                 D! = SQR((SodiumPos!(N%%, 0) - SodiumPos!(L%%, 0)) * (SodiumPos!(N%%, 0) - SodiumPos!(L%%, 0)) + (SodiumPos!(N%%, 1) - SodiumPos!(L%%, 1)) * (SodiumPos!(N%%, 1) - SodiumPos!(L%%, 1)) + (SodiumPos!(N%%, 2) - SodiumPos!(L%%, 2)) * (SodiumPos!(N%%, 2) - SodiumPos!(L%%, 2)))
  87.                 F! = -(Attraction(D!)) / 3000
  88.                 FOR M%% = 0 TO 2
  89.                     SodiumAcc!(N%%, M%%) = -F! * (SodiumPos!(N%%, M%%) - SodiumPos!(L%%, M%%)) / D! + SodiumAcc!(N%%, M%%)
  90.                 NEXT M%%
  91.                 D! = SQR((ChlorinePos!(N%%, 0) - ChlorinePos!(L%%, 0)) * (ChlorinePos!(N%%, 0) - ChlorinePos!(L%%, 0)) + (ChlorinePos!(N%%, 1) - ChlorinePos!(L%%, 1)) * (ChlorinePos!(N%%, 1) - ChlorinePos!(L%%, 1)) + (ChlorinePos!(N%%, 2) - ChlorinePos!(L%%, 2)) * (ChlorinePos!(N%%, 2) - ChlorinePos!(L%%, 2)))
  92.                 F! = -(Attraction(D!)) / 3000
  93.                 FOR M%% = 0 TO 2
  94.                     ChlorineAcc!(N%%, M%%) = -F! * (ChlorinePos!(N%%, M%%) - ChlorinePos!(L%%, M%%)) / D! + ChlorineAcc!(N%%, M%%)
  95.                 NEXT M%%
  96.             END IF
  97.         NEXT L%%
  98.         FOR M%% = 0 TO 2
  99.             SodiumPos!(N%%, M%%) = SodiumPos!(N%%, M%%) + SodiumVel!(N%%, M%%)
  100.             ChlorinePos!(N%%, M%%) = ChlorinePos!(N%%, M%%) + ChlorineVel!(N%%, M%%)
  101.             SodiumVel!(N%%, M%%) = SodiumVel!(N%%, M%%) + SodiumAcc!(N%%, M%%)
  102.             IF ABS(SodiumVel!(N%%, M%%)) > 0.3 THEN SodiumVel!(N%%, M%%) = 0.3 * (ABS(SodiumVel!(N%%, M%%)) / SodiumVel!(N%%, M%%))
  103.             ChlorineVel!(N%%, M%%) = ChlorineVel!(N%%, M%%) + ChlorineAcc!(N%%, M%%)
  104.             IF ABS(ChlorineVel!(N%%, M%%)) > 0.3 THEN ChlorineVel!(N%%, M%%) = 0.3 * (ABS(ChlorineVel!(N%%, M%%)) / ChlorineVel!(N%%, M%%))
  105.         NEXT M%%
  106.     NEXT N%%
  107.     _DISPLAY
  108.  
  109.  
  110. 'FUNCTION MakeHardware& (Imagename&)
  111. '    MakeHardware& = _COPYIMAGE(Imagename&, 33)
  112. '    _FREEIMAGE Imagename&
  113. 'END FUNCTION
  114.  
  115. FUNCTION Attraction (Dist!)
  116.     Attraction = A0! * (1 / (Dist! / A2!) ^ A1!)
  117.  
  118. FUNCTION Repulsion (Dist!)
  119.     Repulsion = -R0! * (1 / (Dist! / R2!) ^ R1!)
  120.  
  121. SUB CentreOfMass 'fio centre of mass adjustment & zero net momentums
  122.     TotMass# = 0
  123.     MRx# = 0: MRy# = 0: MRz# = 0
  124.     Px# = 0: Py# = 0: Pz# = 0
  125.     FOR N% = 0 TO NoBalls%% - 1
  126.         TotMass# = TotMass# + 1
  127.         MRx# = MRx# + SodiumPos!(N%, 0)
  128.         MRy# = MRy# + SodiumPos!(N%, 1)
  129.         MRz# = MRz# + SodiumPos!(N%, 2)
  130.         Px# = SodiumVel!(N%, 0) + Px#
  131.         Py# = SodiumVel!(N%, 1) + Py#
  132.         Pz# = SodiumVel!(N%, 2) + Pz#
  133.         TotMass# = TotMass# + 1
  134.         MRx# = MRx# + ChlorinePos!(N%, 0)
  135.         MRy# = MRy# + ChlorinePos!(N%, 1)
  136.         MRz# = MRz# + ChlorinePos!(N%, 2)
  137.         Px# = ChlorineVel!(N%, 0) + Px#
  138.         Py# = ChlorineVel!(N%, 1) + Py#
  139.         Pz# = ChlorineVel!(N%, 2) + Pz#
  140.     NEXT N%
  141.     FOR N% = 0 TO NoBalls%% - 1
  142.         SodiumPos!(N%, 0) = SodiumPos!(N%, 0) - (MRx# / TotMass#)
  143.         SodiumPos!(N%, 1) = SodiumPos!(N%, 1) - (MRy# / TotMass#)
  144.         SodiumPos!(N%, 2) = SodiumPos!(N%, 2) - (MRz# / TotMass#)
  145.         SodiumVel!(N%, 0) = SodiumVel!(N%, 0) - (Px# / TotMass#)
  146.         SodiumVel!(N%, 1) = SodiumVel!(N%, 1) - (Py# / TotMass#)
  147.         SodiumVel!(N%, 2) = SodiumVel!(N%, 2) - (Pz# / TotMass#)
  148.         ChlorinePos!(N%, 0) = ChlorinePos!(N%, 0) - (MRx# / TotMass#)
  149.         ChlorinePos!(N%, 1) = ChlorinePos!(N%, 1) - (MRy# / TotMass#)
  150.         ChlorinePos!(N%, 2) = ChlorinePos!(N%, 2) - (MRz# / TotMass#)
  151.         ChlorineVel!(N%, 0) = ChlorineVel!(N%, 0) - (Px# / TotMass#)
  152.         ChlorineVel!(N%, 1) = ChlorineVel!(N%, 1) - (Py# / TotMass#)
  153.         ChlorineVel!(N%, 2) = ChlorineVel!(N%, 2) - (Pz# / TotMass#)
  154.     NEXT N%
  155.  

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Sodium Chloride
« Reply #1 on: November 13, 2018, 06:30:48 am »
Version 2.  More atoms (smaller ball size), showing "bond formation", rotating view.

Code: QB64: [Select]
  1. 'Simple Model of Ionic Crystal v2 by QWERKEY 2018-11-12
  2.  
  3. CONST A0! = 100, A1! = 2, R0! = 250, R1! = 2.3, A2! = 200, R2! = 115, FMin! = -5 '-55
  4. CONST NoBalls%% = 100, Atom! = 95, Kelvin! = 0.35, F1! = 1000, F2! = 3000, Theta! = 0.0084
  5.  
  6. DIM BallStats%(1, 2), Cyperium&(1)
  7. DIM SHARED SodiumPos!(NoBalls%% - 1, 2), ChlorinePos!(NoBalls%% - 1, 2) 'Sodium 1, Chlorine 0
  8. DIM SHARED SodiumVel!(NoBalls%% - 1, 2), ChlorineVel!(NoBalls%% - 1, 2)
  9. DIM SodiumAcc!(NoBalls%% - 1, 2), ChlorineAcc!(NoBalls%% - 1, 2)
  10. CONST BallSize1%% = 25, BallSize0%% = 30, Offset% = 730, ScreenX% = 1260, ScreenY% = 800
  11.  
  12. _TITLE "Very Accurate Quantum Physics Model"
  13.  
  14. FOR N%% = 0 TO NoBalls%% - 1
  15.     FOR M%% = 0 TO 2
  16.         ChlorinePos!(N%%, M%%) = 1.5 * ScreenX% * (RND - 0.5) '/ 1.5
  17.         SodiumPos!(N%%, M%%) = 1.5 * ScreenX% * (RND - 0.5) '/ 1.5
  18.         ChlorineVel!(N%%, M%%) = (RND - 0.5) * Kelvin!
  19.         SodiumVel!(N%%, M%%) = (RND - 0.5) * Kelvin!
  20.     NEXT M%%
  21. NEXT N%%
  22.  
  23. ' Ball Colours (Cyperium Method)
  24. DATA 0,0,255
  25. DATA 255,0,0
  26. FOR N%% = 0 TO 1
  27.     FOR P%% = 0 TO 2
  28.         READ BallStats%(N%%, P%%)
  29.     NEXT P%%
  30.     TempImage& = _NEWIMAGE(256, 256, 32)
  31.     _DEST TempImage&
  32.     COLOR _RGBA(BallStats%(N%%, 0), BallStats%(N%%, 1), BallStats%(N%%, 2), 65), _RGBA(0, 0, 0, 0)
  33.     'Image data goes from 1 to 255 (not 0 to 255)
  34.     FOR Z% = 128 TO 255
  35.         FOR X% = 1 TO 255
  36.             FOR Y% = 1 TO 255
  37.                 DeltaX% = X% - 127
  38.                 DeltaY% = Y% - 127
  39.                 DeltaZ% = Z% - 127
  40.                 Dist! = SQR((DeltaX% * DeltaX%) + (DeltaY% * DeltaY%) + (DeltaZ% * DeltaZ%))
  41.                 IF Dist! > 125 AND Dist! < 127 THEN PSET (X%, Y%), _RGBA(CINT(Z% * BallStats%(N%%, 0) * (1 - (XBright! * X% / 255)) / 255), CINT(Z% * BallStats%(N%%, 1) * (1 - (XBright! * X% / 255)) / 255), CINT(Z% * BallStats%(N%%, 2) * (1 - (XBright! * X% / 255)) / 255), 65)
  42.             NEXT
  43.         NEXT
  44.     NEXT
  45.     Cyperium&(N%%) = _COPYIMAGE(TempImage&)
  46.     _FREEIMAGE TempImage&
  47. NEXT N%%
  48.  
  49. Sodium& = _COPYIMAGE(Cyperium&(1), 33)
  50. _FREEIMAGE Cyperium&(1)
  51. Chlorine& = _COPYIMAGE(Cyperium&(0), 33)
  52. _FREEIMAGE Cyperium&(0)
  53. TempImage& = _NEWIMAGE(102, 2, 32)
  54. _DEST TempImage&
  55. LINE (0, 0)-(101, 1), _RGB32(255, 255, 255), BF
  56. LineImage& = _COPYIMAGE(TempImage&, 33)
  57. _FREEIMAGE TempImage&
  58.  
  59. 'Create screen
  60. SCREEN _NEWIMAGE(ScreenX%, ScreenY%, 32)
  61. _DISPLAYORDER _HARDWARE ', _SOFTWARE 'do not even render the software layer, just the hardware one.
  62.  
  63.     _LIMIT 25
  64.     CALL CentreOfMass
  65.     MaxDist! = 0
  66.     FOR N%% = 0 TO NoBalls%% - 1
  67.         _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Chlorine& TO(-(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), (BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)-((BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), (BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)-(-(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), -(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)
  68.         _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Chlorine& TO((BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), -(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)-(-(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), -(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)-((BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 0), (BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ChlorinePos!(N%%, 2) - Offset%)
  69.         _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Sodium& TO(-(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), (BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)-((BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), (BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)-(-(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), -(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)
  70.         _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Sodium& TO((BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), -(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)-(-(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), -(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)-((BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 0), (BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)
  71.         FOR M%% = 0 TO 2
  72.             SodiumAcc!(N%%, M%%) = 0
  73.         NEXT M%%
  74.         FOR M%% = 0 TO 2
  75.             ChlorineAcc!(N%%, M%%) = 0
  76.         NEXT M%%
  77.         FOR L%% = 0 TO NoBalls%% - 1
  78.             'opposites
  79.             D! = SQR((SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)) * (SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)) + (SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)) * (SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)) + (SodiumPos!(N%%, 2) - ChlorinePos!(L%%, 2)) * (SodiumPos!(N%%, 2) - ChlorinePos!(L%%, 2)))
  80.             F! = (Attraction!(D!) + Repulsion!(D!)) / F1!
  81.             'IF F! < FMin! / F1! THEN F! = FMin! / F1!
  82.             FOR M%% = 0 TO 2
  83.                 SodiumAcc!(N%%, M%%) = -F! * (SodiumPos!(N%%, M%%) - ChlorinePos!(L%%, M%%)) / D! + SodiumAcc!(N%%, M%%)
  84.             NEXT M%%
  85.             IF D! < Atom! THEN _MAPTRIANGLE (0, 0)-(101, 0)-(101, 1), LineImage& TO(SodiumPos!(N%%, 0), SodiumPos!(N%%, 1), SodiumPos!(N%%, 2) - Offset%)-(ChlorinePos!(L%%, 0), ChlorinePos!(L%%, 1), ChlorinePos!(L%%, 2) - Offset%)-(ChlorinePos!(L%%, 0), ChlorinePos!(L%%, 1), ChlorinePos!(L%%, 2) - Offset% - 1), , _SMOOTH
  86.             D! = SQR((SodiumPos!(L%%, 0) - ChlorinePos!(N%%, 0)) * (SodiumPos!(L%%, 0) - ChlorinePos!(N%%, 0)) + (SodiumPos!(L%%, 1) - ChlorinePos!(N%%, 1)) * (SodiumPos!(L%%, 1) - ChlorinePos!(N%%, 1)) + (SodiumPos!(L%%, 2) - ChlorinePos!(N%%, 2)) * (SodiumPos!(L%%, 2) - ChlorinePos!(N%%, 2)))
  87.             F! = (Attraction!(D!) + Repulsion!(D!)) / F1!
  88.             'IF F! < FMin! / F1! THEN F! = FMin! / F1!
  89.             FOR M%% = 0 TO 2
  90.                 ChlorineAcc!(N%%, M%%) = F! * (SodiumPos!(L%%, M%%) - ChlorinePos!(N%%, M%%)) / D! + ChlorineAcc!(N%%, M%%)
  91.             NEXT M%%
  92.             IF L%% <> N%% THEN
  93.                 'same type
  94.                 D! = SQR((SodiumPos!(N%%, 0) - SodiumPos!(L%%, 0)) * (SodiumPos!(N%%, 0) - SodiumPos!(L%%, 0)) + (SodiumPos!(N%%, 1) - SodiumPos!(L%%, 1)) * (SodiumPos!(N%%, 1) - SodiumPos!(L%%, 1)) + (SodiumPos!(N%%, 2) - SodiumPos!(L%%, 2)) * (SodiumPos!(N%%, 2) - SodiumPos!(L%%, 2)))
  95.                 F! = -(Attraction!(D!)) / F2!
  96.                 FOR M%% = 0 TO 2
  97.                     SodiumAcc!(N%%, M%%) = -F! * (SodiumPos!(N%%, M%%) - SodiumPos!(L%%, M%%)) / D! + SodiumAcc!(N%%, M%%)
  98.                 NEXT M%%
  99.                 D! = SQR((ChlorinePos!(N%%, 0) - ChlorinePos!(L%%, 0)) * (ChlorinePos!(N%%, 0) - ChlorinePos!(L%%, 0)) + (ChlorinePos!(N%%, 1) - ChlorinePos!(L%%, 1)) * (ChlorinePos!(N%%, 1) - ChlorinePos!(L%%, 1)) + (ChlorinePos!(N%%, 2) - ChlorinePos!(L%%, 2)) * (ChlorinePos!(N%%, 2) - ChlorinePos!(L%%, 2)))
  100.                 F! = -(Attraction!(D!)) / F2!
  101.                 FOR M%% = 0 TO 2
  102.                     ChlorineAcc!(N%%, M%%) = -F! * (ChlorinePos!(N%%, M%%) - ChlorinePos!(L%%, M%%)) / D! + ChlorineAcc!(N%%, M%%)
  103.                 NEXT M%%
  104.             END IF
  105.         NEXT L%%
  106.         FOR M%% = 0 TO 2
  107.             SodiumPos!(N%%, M%%) = SodiumPos!(N%%, M%%) + SodiumVel!(N%%, M%%)
  108.             ChlorinePos!(N%%, M%%) = ChlorinePos!(N%%, M%%) + ChlorineVel!(N%%, M%%)
  109.             SodiumVel!(N%%, M%%) = SodiumVel!(N%%, M%%) + SodiumAcc!(N%%, M%%)
  110.             IF ABS(SodiumVel!(N%%, M%%)) > Kelvin! THEN SodiumVel!(N%%, M%%) = Kelvin! * (ABS(SodiumVel!(N%%, M%%)) / SodiumVel!(N%%, M%%))
  111.             ChlorineVel!(N%%, M%%) = ChlorineVel!(N%%, M%%) + ChlorineAcc!(N%%, M%%)
  112.             IF ABS(ChlorineVel!(N%%, M%%)) > Kelvin! THEN ChlorineVel!(N%%, M%%) = Kelvin! * (ABS(ChlorineVel!(N%%, M%%)) / ChlorineVel!(N%%, M%%))
  113.         NEXT M%%
  114.         XTemp! = SodiumPos!(N%%, 0)
  115.         SodiumPos!(N%%, 0) = XDash!(SodiumPos!(N%%, 0), SodiumPos!(N%%, 2))
  116.         SodiumPos!(N%%, 2) = ZDash!(XTemp!, SodiumPos!(N%%, 2))
  117.         XTemp! = ChlorinePos!(N%%, 0)
  118.         ChlorinePos!(N%%, 0) = XDash!(ChlorinePos!(N%%, 0), ChlorinePos!(N%%, 2))
  119.         ChlorinePos!(N%%, 2) = ZDash!(XTemp!, ChlorinePos!(N%%, 2))
  120.         'SodiumDist! = SQR(SodiumPos!(N%%, 0) * SodiumPos!(N%%, 0) + SodiumPos!(N%%, 1) * SodiumPos!(N%%, 1) + SodiumPos!(N%%, 2) * SodiumPos!(N%%, 2))
  121.         'IF SodiumDist! > MaxDist! THEN MaxDist! = SodiumDist!
  122.         'ChlorineDist! = SQR(ChlorinePos!(N%%, 0) * ChlorinePos!(N%%, 0) + ChlorinePos!(N%%, 1) * ChlorinePos!(N%%, 1) + ChlorinePos!(N%%, 2) * ChlorinePos!(N%%, 2))
  123.         'IF ChlorineDist! > MaxDist! THEN MaxDist! = ChlorineDist!
  124.         'LOCATE 1, 1: PRINT MaxDist!
  125.     NEXT N%%
  126.     _DISPLAY
  127.  
  128.  
  129. 'FUNCTION MakeHardware& (Imagename&)
  130. '    MakeHardware& = _COPYIMAGE(Imagename&, 33)
  131. '    _FREEIMAGE Imagename&
  132. 'END FUNCTION
  133.  
  134. FUNCTION Attraction! (Dist!)
  135.     Attraction! = A0! * (1 / (Dist! / A2!) ^ A1!)
  136.  
  137. FUNCTION Repulsion! (Dist!)
  138.     Repulsion! = -R0! * (1 / (Dist! / R2!) ^ R1!)
  139.  
  140. FUNCTION XDash! (X!, Z!)
  141.     XDash! = X! * COS(Theta!) + Z! * SIN(Theta!)
  142.  
  143. FUNCTION ZDash! (X!, Z!)
  144.     ZDash! = -X! * SIN(Theta!) + Z! * COS(Theta!)
  145.  
  146. SUB CentreOfMass 'fio centre of mass adjustment & zero net momentums
  147.     TotMass# = 0
  148.     MRx# = 0: MRy# = 0: MRz# = 0
  149.     Px# = 0: Py# = 0: Pz# = 0
  150.     FOR N% = 0 TO NoBalls%% - 1
  151.         TotMass# = TotMass# + 1
  152.         MRx# = MRx# + SodiumPos!(N%, 0)
  153.         MRy# = MRy# + SodiumPos!(N%, 1)
  154.         MRz# = MRz# + SodiumPos!(N%, 2)
  155.         Px# = SodiumVel!(N%, 0) + Px#
  156.         Py# = SodiumVel!(N%, 1) + Py#
  157.         Pz# = SodiumVel!(N%, 2) + Pz#
  158.         TotMass# = TotMass# + 1
  159.         MRx# = MRx# + ChlorinePos!(N%, 0)
  160.         MRy# = MRy# + ChlorinePos!(N%, 1)
  161.         MRz# = MRz# + ChlorinePos!(N%, 2)
  162.         Px# = ChlorineVel!(N%, 0) + Px#
  163.         Py# = ChlorineVel!(N%, 1) + Py#
  164.         Pz# = ChlorineVel!(N%, 2) + Pz#
  165.     NEXT N%
  166.     FOR N% = 0 TO NoBalls%% - 1
  167.         SodiumPos!(N%, 0) = SodiumPos!(N%, 0) - (MRx# / TotMass#)
  168.         SodiumPos!(N%, 1) = SodiumPos!(N%, 1) - (MRy# / TotMass#)
  169.         SodiumPos!(N%, 2) = SodiumPos!(N%, 2) - (MRz# / TotMass#)
  170.         SodiumVel!(N%, 0) = SodiumVel!(N%, 0) - (Px# / TotMass#)
  171.         SodiumVel!(N%, 1) = SodiumVel!(N%, 1) - (Py# / TotMass#)
  172.         SodiumVel!(N%, 2) = SodiumVel!(N%, 2) - (Pz# / TotMass#)
  173.         ChlorinePos!(N%, 0) = ChlorinePos!(N%, 0) - (MRx# / TotMass#)
  174.         ChlorinePos!(N%, 1) = ChlorinePos!(N%, 1) - (MRy# / TotMass#)
  175.         ChlorinePos!(N%, 2) = ChlorinePos!(N%, 2) - (MRz# / TotMass#)
  176.         ChlorineVel!(N%, 0) = ChlorineVel!(N%, 0) - (Px# / TotMass#)
  177.         ChlorineVel!(N%, 1) = ChlorineVel!(N%, 1) - (Py# / TotMass#)
  178.         ChlorineVel!(N%, 2) = ChlorineVel!(N%, 2) - (Pz# / TotMass#)
  179.     NEXT N%
  180.  

FellippeHeitor

  • Guest
Re: Sodium Chloride
« Reply #2 on: November 13, 2018, 06:55:31 am »
I'm here for the looks as all that science flies way over my head. Great job! Second version looks really hypnotic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sodium Chloride
« Reply #3 on: November 13, 2018, 08:28:19 am »
Yes, 2nd version is amazing!

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Sodium Chloride
« Reply #4 on: November 13, 2018, 08:40:18 am »
bplus & Fellippe, you are too kind.  No! What is really amazing is _MAPTRIANGLE(3D) and QB64 behind it.  No wonder that it is beginning to be taught in schools.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Sodium Chloride
« Reply #5 on: November 13, 2018, 04:08:46 pm »
Have yet to look closely at the physics here, but the first thing that catches my eye is the molecules make a sphere instead of a lattice. Increasing your coulomb force should do it at a glance, even in a newtonian approximation.
You're not done when it works, you're done when it's right.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Sodium Chloride
« Reply #6 on: November 13, 2018, 05:38:13 pm »
I agree. Let Bill fool around with your balls and who knows what could come of it?

I love it! I tutored chemistry in pre-med. I would have loved to have had a project like this one, but dammit, we only had typewriters, no computers. Of course I'd have to swap the colors.  Everyone knows Sodium is good and Chlorine is evil, so Sodium should be represented by the Republican color of red! Sorry, still too close the the U.S. mid-term elections.

Looking forward to seeing what kind of spin Bill puts on your bal... atoms.

Pete :D

PS Scary, I was just proofing my post and had the strangest feeling of Deja vu.
« Last Edit: November 14, 2018, 06:21:15 am by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Sodium Chloride
« Reply #7 on: November 14, 2018, 04:45:41 am »
Have yet to look closely at the physics here, but the first thing that catches my eye is the molecules make a sphere instead of a lattice. Increasing your coulomb force should do it at a glance, even in a newtonian approximation.
STxAxTIC, I think that the spherical clustering arises because I have not used electronic structure bonding, but simple inverse-square (spherical) attraction.  The ions attract each other and try to form the smallest-possible volume, which is a sphere.  I did say that I might try a more realistic force model at some point.  You may have been persuaded that I was doing something more complex by the post's title, as if I really were modelling sodium chloride (as opposed to, say, diamond*) - the title was merely to entice members: the "sodium" ions are only smaller in the graphic, not in the force model.

But you have got me thinking about how I might get the ions to try to produce a cubic structure with a preference to produce flat surfaces.  That is a challenge, but an interesting one.

* As everybody knows (of course you do, Fellippe!), the diamond structure is two interpenetrating face-centred cubics offset by a quarter of the lattice diagonal.

 

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Sodium Chloride
« Reply #8 on: November 14, 2018, 04:51:28 am »
Everyone knows Sodium is good and Chlorine is evil, so Sodium should be represented by the Republican color of red!

Oh Crikey!  Pete has even managed to bring politics into Coulombic force modelling.  I'm going to bring up Brexit in everybody's posts!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Sodium Chloride
« Reply #9 on: November 14, 2018, 06:20:01 am »
Well if you don't, Tersea May.

Pete :D
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Sodium Chloride
« Reply #10 on: November 14, 2018, 08:03:25 am »
Something tells me you took solid state physics before!
You're not done when it works, you're done when it's right.

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Sodium Chloride
« Reply #11 on: November 14, 2018, 09:23:44 am »
Hi! I see (in simulation) some NaCl atom which also make bond with another Na or Cl atom. Is this correct?
As, the NaCl is already stable.
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sodium Chloride
« Reply #12 on: November 14, 2018, 10:20:10 am »
Hi! I see (in simulation) some NaCl atom which also make bond with another Na or Cl atom. Is this correct?
As, the NaCl is already stable.

https://www.google.com/search?q=sodium+chloride+molecular+structure&client=opera&hs=2mz&tbm=isch&tbo=u&source=univ&sa=X&ved=2ahUKEwjJt-zKldTeAhVSyYMKHTpUDCIQsAR6BAgEEAE&biw=1285&bih=667#imgrc=62v5tCHLkTmjLM:

I don't remember much chemistry but as I recall Chloride is not picky from which sodium atom it gets an extra electron so several could hang around and share in group hug.  I do remember we are talking about salt that has (slightly slanted?) cubic structure.

I confess I was hoping to see a cubic structure emerge but still, seeing the smaller and larger spheres organize was pretty cool.
« Last Edit: November 14, 2018, 10:34:52 am by bplus »

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Sodium Chloride
« Reply #13 on: November 14, 2018, 12:54:28 pm »
Here's version 4, which is a cheat to make the atoms congregate into a cubic structure.  Pleasing graphics but very bad physics.  (If you're wondering where version 3 is, it's something I did to amuse myself privately).  I will try to do some proper physics for later versions.  I've removed the bond lines in this version as the flicker degrades the graphics.

Code: QB64: [Select]
  1. 'Simple Model of Ionic Crystal v4 by QWERKEY 2018-11-14
  2.  
  3. CONST A0! = 100, A1! = 2, R0! = 250, R1! = 2.3, A2! = 200, R2! = 115, FMin! = -5 '-55
  4. CONST NoBalls%% = 100, Atom! = 120, Kelvin! = 0.35, F1! = 1000, F2! = 3000, Xstal! = 0.99
  5. CONST BallSize1%% = 25, BallSize0%% = 30, Offset% = 730, ScreenX% = 1260, ScreenY% = 800
  6.  
  7. DIM SHARED SodiumPos!(NoBalls%% - 1, 2), ChlorinePos!(NoBalls%% - 1, 2) 'Sodium 1, Chlorine 0
  8. DIM SHARED SodiumVel!(NoBalls%% - 1, 2), ChlorineVel!(NoBalls%% - 1, 2), Theta! '= 0.0084
  9. DIM SodiumAcc!(NoBalls%% - 1, 2), ChlorineAcc!(NoBalls%% - 1, 2), BallStats%(1, 2)
  10.  
  11. _TITLE "Very Accurate Quantum Physics Model"
  12.  
  13. OPEN "temp.txt" FOR OUTPUT AS #1
  14.  
  15. FOR N%% = 0 TO NoBalls%% - 1
  16.     FOR M%% = 0 TO 2
  17.         ChlorinePos!(N%%, M%%) = 1.5 * ScreenX% * (RND - 0.5)
  18.         SodiumPos!(N%%, M%%) = 1.5 * ScreenX% * (RND - 0.5)
  19.         ChlorineVel!(N%%, M%%) = (RND - 0.5) * Kelvin!
  20.         SodiumVel!(N%%, M%%) = (RND - 0.5) * Kelvin!
  21.     NEXT M%%
  22. NEXT N%%
  23.  
  24. ' Ball Colours (Cyperium Method)
  25. DATA 0,0,255
  26. DATA 255,0,0
  27. FOR N%% = 0 TO 1
  28.     FOR P%% = 0 TO 2
  29.         READ BallStats%(N%%, P%%)
  30.     NEXT P%%
  31.     TempImage& = _NEWIMAGE(256, 256, 32)
  32.     _DEST TempImage&
  33.     COLOR _RGBA(BallStats%(N%%, 0), BallStats%(N%%, 1), BallStats%(N%%, 2), 65), _RGBA(0, 0, 0, 0)
  34.     'Image data goes from 1 to 255 (not 0 to 255)
  35.     FOR Z% = 128 TO 255
  36.         FOR X% = 1 TO 255
  37.             FOR Y% = 1 TO 255
  38.                 DeltaX% = X% - 127
  39.                 DeltaY% = Y% - 127
  40.                 DeltaZ% = Z% - 127
  41.                 Dist! = SQR((DeltaX% * DeltaX%) + (DeltaY% * DeltaY%) + (DeltaZ% * DeltaZ%))
  42.                 IF Dist! > 125 AND Dist! < 127 THEN PSET (X%, Y%), _RGBA(CINT(Z% * BallStats%(N%%, 0) * (1 - (XBright! * X% / 255)) / 255), CINT(Z% * BallStats%(N%%, 1) * (1 - (XBright! * X% / 255)) / 255), CINT(Z% * BallStats%(N%%, 2) * (1 - (XBright! * X% / 255)) / 255), 65)
  43.             NEXT
  44.         NEXT
  45.     NEXT
  46.     IF N%% = 0 THEN
  47.         Chlorine& = _COPYIMAGE(TempImage&, 33)
  48.     ELSE
  49.         Sodium& = _COPYIMAGE(TempImage&, 33)
  50.     END IF
  51.     _FREEIMAGE TempImage&
  52. NEXT N%%
  53.  
  54. TempImage& = _NEWIMAGE(102, 2, 32)
  55. _DEST TempImage&
  56. LINE (0, 0)-(101, 1), _RGB32(255, 255, 255), BF
  57. LineImage& = _COPYIMAGE(TempImage&, 33)
  58. _FREEIMAGE TempImage&
  59.  
  60. 'Create screen
  61. SCREEN _NEWIMAGE(ScreenX%, ScreenY%, 32)
  62. _DISPLAYORDER _HARDWARE ', _SOFTWARE 'do not even render the software layer, just the hardware one.
  63.  
  64.     _LIMIT 25
  65.     CALL CentreOfMass
  66.     MaxDist! = 0
  67.     FOR N%% = 0 TO NoBalls%% - 1
  68.         XTemp! = ChlorinePos!(N%%, 0): ZTemp! = ChlorinePos!(N%%, 2)
  69.         _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Chlorine& TO(-(BallSize1%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), (BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)-((BallSize1%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), (BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)-(-(BallSize1%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), -(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)
  70.         _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Chlorine& TO((BallSize1%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), -(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)-(-(BallSize1%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), -(BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)-((BallSize1%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), (BallSize1%% - 1) \ 2 + ChlorinePos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)
  71.         XTemp! = SodiumPos!(N%%, 0): ZTemp! = SodiumPos!(N%%, 2)
  72.         _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Sodium& TO(-(BallSize0%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), (BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)-((BallSize0%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), (BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)-(-(BallSize0%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), -(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)
  73.         _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Sodium& TO((BallSize0%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), -(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)-(-(BallSize0%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), -(BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)-((BallSize0%% - 1) \ 2 + XDash!(XTemp!, ZTemp!), (BallSize0%% - 1) \ 2 + SodiumPos!(N%%, 1), ZDash!(XTemp!, ZTemp!) - Offset%)
  74.         FOR M%% = 0 TO 2
  75.             SodiumAcc!(N%%, M%%) = 0
  76.         NEXT M%%
  77.         FOR M%% = 0 TO 2
  78.             ChlorineAcc!(N%%, M%%) = 0
  79.         NEXT M%%
  80.         FOR L%% = 0 TO NoBalls%% - 1
  81.             'opposites
  82.             D! = SQR((SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)) * (SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)) + (SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)) * (SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)) + (SodiumPos!(N%%, 2) - ChlorinePos!(L%%, 2)) * (SodiumPos!(N%%, 2) - ChlorinePos!(L%%, 2)))
  83.             F! = (Attraction!(D!) + Repulsion!(D!)) / F1!
  84.             'IF F! < FMin! / F1! THEN F! = FMin! / F1!
  85.             FOR M%% = 0 TO 2
  86.                 SodiumAcc!(N%%, M%%) = -F! * (SodiumPos!(N%%, M%%) - ChlorinePos!(L%%, M%%)) / D! + SodiumAcc!(N%%, M%%)
  87.             NEXT M%%
  88.             IF D! < Atom! THEN
  89.                 '_MAPTRIANGLE (0, 0)-(101, 0)-(101, 1), LineImage& TO(XDash!(SodiumPos!(N%%, 0), SodiumPos!(N%%, 2)), SodiumPos!(N%%, 1), ZDash!(SodiumPos!(N%%, 0), SodiumPos!(N%%, 2)) - Offset%)-(XDash!(ChlorinePos!(L%%, 0), ChlorinePos!(L%%, 2)), ChlorinePos!(L%%, 1), ZDash!(ChlorinePos!(L%%, 0), ChlorinePos!(L%%, 2)) - Offset%)-(XDash!(ChlorinePos!(L%%, 0), ChlorinePos!(L%%, 2)), ChlorinePos!(L%%, 1), ZDash!(ChlorinePos!(L%%, 0), ChlorinePos!(L%%, 2)) - Offset% - 1), , _SMOOTH
  90.                 IF ABS(SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)) > ABS(SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)) AND ABS(SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)) > ABS(SodiumPos!(N%%, 2) - ChlorinePos!(L%%, 2)) THEN
  91.                     delta! = SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)
  92.                     SodiumPos!(N%%, 1) = SodiumPos!(N%%, 1) + delta! * (1 - Xstal!)
  93.                     ChlorinePos!(L%%, 1) = ChlorinePos!(L%%, 1) - delta! * (1 - Xstal!)
  94.                     delta! = SodiumPos!(N%%, 2) - ChlorinePos!(L%%, 2)
  95.                     SodiumPos!(N%%, 2) = SodiumPos!(N%%, 2) + delta! * (1 - Xstal!)
  96.                     ChlorinePos!(L%%, 2) = ChlorinePos!(L%%, 2) - delta! * (1 - Xstal!)
  97.                 ELSEIF ABS(SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)) > ABS(SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)) AND ABS(SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)) > ABS(SodiumPos!(N%%, 2) - ChlorinePos!(L%%, 2)) THEN
  98.                     delta! = SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)
  99.                     SodiumPos!(N%%, 0) = SodiumPos!(N%%, 0) + delta! * (1 - Xstal!)
  100.                     ChlorinePos!(L%%, 0) = ChlorinePos!(L%%, 0) - delta! * (1 - Xstal!)
  101.                     delta! = SodiumPos!(N%%, 2) - ChlorinePos!(L%%, 2)
  102.                     SodiumPos!(N%%, 2) = SodiumPos!(N%%, 2) + delta! * (1 - Xstal!)
  103.                     ChlorinePos!(L%%, 2) = ChlorinePos!(L%%, 2) - delta! * (1 - Xstal!)
  104.                 ELSE
  105.                     delta! = SodiumPos!(N%%, 1) - ChlorinePos!(L%%, 1)
  106.                     SodiumPos!(N%%, 1) = SodiumPos!(N%%, 1) + delta! * (1 - Xstal!)
  107.                     ChlorinePos!(L%%, 1) = ChlorinePos!(L%%, 1) - delta! * (1 - Xstal!)
  108.                     delta! = SodiumPos!(N%%, 0) - ChlorinePos!(L%%, 0)
  109.                     SodiumPos!(N%%, 0) = SodiumPos!(N%%, 0) + delta! * (1 - Xstal!)
  110.                     ChlorinePos!(L%%, 0) = ChlorinePos!(L%%, 0) - delta! * (1 - Xstal!)
  111.                 END IF
  112.             END IF
  113.             D! = SQR((SodiumPos!(L%%, 0) - ChlorinePos!(N%%, 0)) * (SodiumPos!(L%%, 0) - ChlorinePos!(N%%, 0)) + (SodiumPos!(L%%, 1) - ChlorinePos!(N%%, 1)) * (SodiumPos!(L%%, 1) - ChlorinePos!(N%%, 1)) + (SodiumPos!(L%%, 2) - ChlorinePos!(N%%, 2)) * (SodiumPos!(L%%, 2) - ChlorinePos!(N%%, 2)))
  114.             F! = (Attraction!(D!) + Repulsion!(D!)) / F1!
  115.             'IF F! < FMin! / F1! THEN F! = FMin! / F1!
  116.             FOR M%% = 0 TO 2
  117.                 ChlorineAcc!(N%%, M%%) = F! * (SodiumPos!(L%%, M%%) - ChlorinePos!(N%%, M%%)) / D! + ChlorineAcc!(N%%, M%%)
  118.             NEXT M%%
  119.             IF L%% <> N%% THEN
  120.                 'same type
  121.                 D! = SQR((SodiumPos!(N%%, 0) - SodiumPos!(L%%, 0)) * (SodiumPos!(N%%, 0) - SodiumPos!(L%%, 0)) + (SodiumPos!(N%%, 1) - SodiumPos!(L%%, 1)) * (SodiumPos!(N%%, 1) - SodiumPos!(L%%, 1)) + (SodiumPos!(N%%, 2) - SodiumPos!(L%%, 2)) * (SodiumPos!(N%%, 2) - SodiumPos!(L%%, 2)))
  122.                 F! = -(Attraction!(D!)) / F2!
  123.                 FOR M%% = 0 TO 2
  124.                     SodiumAcc!(N%%, M%%) = -F! * (SodiumPos!(N%%, M%%) - SodiumPos!(L%%, M%%)) / D! + SodiumAcc!(N%%, M%%)
  125.                 NEXT M%%
  126.                 D! = SQR((ChlorinePos!(N%%, 0) - ChlorinePos!(L%%, 0)) * (ChlorinePos!(N%%, 0) - ChlorinePos!(L%%, 0)) + (ChlorinePos!(N%%, 1) - ChlorinePos!(L%%, 1)) * (ChlorinePos!(N%%, 1) - ChlorinePos!(L%%, 1)) + (ChlorinePos!(N%%, 2) - ChlorinePos!(L%%, 2)) * (ChlorinePos!(N%%, 2) - ChlorinePos!(L%%, 2)))
  127.                 F! = -(Attraction!(D!)) / F2!
  128.                 FOR M%% = 0 TO 2
  129.                     ChlorineAcc!(N%%, M%%) = -F! * (ChlorinePos!(N%%, M%%) - ChlorinePos!(L%%, M%%)) / D! + ChlorineAcc!(N%%, M%%)
  130.                 NEXT M%%
  131.             END IF
  132.         NEXT L%%
  133.         FOR M%% = 0 TO 2
  134.             SodiumPos!(N%%, M%%) = SodiumPos!(N%%, M%%) + SodiumVel!(N%%, M%%)
  135.             ChlorinePos!(N%%, M%%) = ChlorinePos!(N%%, M%%) + ChlorineVel!(N%%, M%%)
  136.             SodiumVel!(N%%, M%%) = SodiumVel!(N%%, M%%) + SodiumAcc!(N%%, M%%)
  137.             IF ABS(SodiumVel!(N%%, M%%)) > Kelvin! THEN SodiumVel!(N%%, M%%) = Kelvin! * (ABS(SodiumVel!(N%%, M%%)) / SodiumVel!(N%%, M%%))
  138.             ChlorineVel!(N%%, M%%) = ChlorineVel!(N%%, M%%) + ChlorineAcc!(N%%, M%%)
  139.             IF ABS(ChlorineVel!(N%%, M%%)) > Kelvin! THEN ChlorineVel!(N%%, M%%) = Kelvin! * (ABS(ChlorineVel!(N%%, M%%)) / ChlorineVel!(N%%, M%%))
  140.         NEXT M%%
  141.     NEXT N%%
  142.     Theta! = Theta! + 0.0084
  143.     IF Theta! > 2 * _PI THEN Theta! = Theta! - 2 * _PI
  144.     _DISPLAY
  145.  
  146.  
  147.  
  148. 'FUNCTION MakeHardware& (Imagename&)
  149. '    MakeHardware& = _COPYIMAGE(Imagename&, 33)
  150. '    _FREEIMAGE Imagename&
  151. 'END FUNCTION
  152.  
  153. FUNCTION Attraction! (Dist!)
  154.     Attraction! = A0! * (1 / (Dist! / A2!) ^ A1!)
  155.  
  156. FUNCTION Repulsion! (Dist!)
  157.     Repulsion! = -R0! * (1 / (Dist! / R2!) ^ R1!)
  158.  
  159. FUNCTION XDash! (X!, Z!)
  160.     XDash! = X! * COS(Theta!) + Z! * SIN(Theta!)
  161.  
  162. FUNCTION ZDash! (X!, Z!)
  163.     ZDash! = -X! * SIN(Theta!) + Z! * COS(Theta!)
  164.  
  165. SUB CentreOfMass 'fio centre of mass adjustment & zero net momentums
  166.     TotMass# = 0
  167.     MRx# = 0: MRy# = 0: MRz# = 0
  168.     Px# = 0: Py# = 0: Pz# = 0
  169.     FOR N% = 0 TO NoBalls%% - 1
  170.         TotMass# = TotMass# + 1
  171.         MRx# = MRx# + SodiumPos!(N%, 0)
  172.         MRy# = MRy# + SodiumPos!(N%, 1)
  173.         MRz# = MRz# + SodiumPos!(N%, 2)
  174.         Px# = SodiumVel!(N%, 0) + Px#
  175.         Py# = SodiumVel!(N%, 1) + Py#
  176.         Pz# = SodiumVel!(N%, 2) + Pz#
  177.         TotMass# = TotMass# + 1
  178.         MRx# = MRx# + ChlorinePos!(N%, 0)
  179.         MRy# = MRy# + ChlorinePos!(N%, 1)
  180.         MRz# = MRz# + ChlorinePos!(N%, 2)
  181.         Px# = ChlorineVel!(N%, 0) + Px#
  182.         Py# = ChlorineVel!(N%, 1) + Py#
  183.         Pz# = ChlorineVel!(N%, 2) + Pz#
  184.     NEXT N%
  185.     FOR N% = 0 TO NoBalls%% - 1
  186.         SodiumPos!(N%, 0) = SodiumPos!(N%, 0) - (MRx# / TotMass#)
  187.         SodiumPos!(N%, 1) = SodiumPos!(N%, 1) - (MRy# / TotMass#)
  188.         SodiumPos!(N%, 2) = SodiumPos!(N%, 2) - (MRz# / TotMass#)
  189.         SodiumVel!(N%, 0) = SodiumVel!(N%, 0) - (Px# / TotMass#)
  190.         SodiumVel!(N%, 1) = SodiumVel!(N%, 1) - (Py# / TotMass#)
  191.         SodiumVel!(N%, 2) = SodiumVel!(N%, 2) - (Pz# / TotMass#)
  192.         ChlorinePos!(N%, 0) = ChlorinePos!(N%, 0) - (MRx# / TotMass#)
  193.         ChlorinePos!(N%, 1) = ChlorinePos!(N%, 1) - (MRy# / TotMass#)
  194.         ChlorinePos!(N%, 2) = ChlorinePos!(N%, 2) - (MRz# / TotMass#)
  195.         ChlorineVel!(N%, 0) = ChlorineVel!(N%, 0) - (Px# / TotMass#)
  196.         ChlorineVel!(N%, 1) = ChlorineVel!(N%, 1) - (Py# / TotMass#)
  197.         ChlorineVel!(N%, 2) = ChlorineVel!(N%, 2) - (Pz# / TotMass#)
  198.     NEXT N%
  199.  

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Sodium Chloride
« Reply #14 on: November 14, 2018, 01:14:56 pm »
No, no, no! You didn't need to make another version. You just needed to tell Mark some of your atoms suffered from bipolar disorder!

I like the effects in version 3 much better.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/