Letztes Jahr (2020) haben wir im Zusammenhang mit der Pandemie eine wissenschaftliche Online-Konferenz über Computerchemie abgehalten und ein Logo dafür erstellt, das, gelinde gesagt, so lala war. Unter dem Schnitt befindet sich eine Geschichte darüber, wie wir es für die Konferenz dieses (2021) Jahres mit einer kleinen Menge Quantenmechanik, der Monte-Carlo-Methode, Python und Gnuplot gepumpt haben.
Ein bisschen Hintergrund
2020 wird die corona an Dynamik gewinnt, Beschränkungen auferlegt werden, und das Niveau der wissenschaftlichen Diskussion zu erhalten, verbessern wissenschaftliche Zusammenarbeit zwischen den russischsprachigen Wissenschaftlern auf der ganzen Welt verstreut ist , und für alle den Rest der gut organisierten wir ein Mini-Symposium zum Thema Computerchemie online .
Aber was ist eine Konferenz ohne Logo? Und nachdem alle künstlerischen (vom Wort "schlecht") Möglichkeiten des Organisationskomitees der Konferenz zusammengefasst wurden, wurde in Inkscape ein Logo erstellt:
. , d- . - Firefly, , , , . , . : ψ, , . , . to Pimp My Ride Logo.
, 2020 , -. . , - ?
. :
,
,
,
, .
- ψ ( ), (x,y,z)=r. . r0, r1, r2, ..., rN, N - . ψn=ψ(rn). , Python :
rn rtrial, (xn,yn,zn) rn -δ +δ, δ — , ,
pacc = |ψtrial|2/|ψn|2, q 0 1, pacc q: pacc<q, (rn+1=rn), , (rn+1=rtrial),
, , -0.1⋅δ +0.1⋅δ.
, , . 10% , , , . .
. d- :
r — r, , . , . , , :
, , .
Python
import numpy as np
import random as rnd
DXYZ = 4.0
dxyz = 0.1*DXYZ
def getWFN(R, a=0.05, b=0.9, R0=1.0):
return (a*(R[1])**3 + b*R[0]*R[1])*np.exp(-np.sqrt(np.dot(R,R))/R0)
Npts = 40000
N2ignore = Npts/10
outf = open("wfn.dat", "w")
outfp = open("wfn_pos.dat", "w")
outfn = open("wfn_neg.dat", "w")
genNewXYZ = lambda xyz, shift: xyz + np.array([rnd.uniform(-shift,shift) for q in range(0,3)])
XYZ = np.array([1.0,1.0,0.0])
Psi = getWFN(XYZ, DXYZ)
for i in range(0,Npts):
trialXYZ = genNewXYZ(XYZ, DXYZ)
trialPsi = getWFN(trialXYZ)
if i % N2ignore == 0:
print("step #%i" % (i))
Ptrial = rnd.random()
Ptest = trialPsi**2/Psi**2
Accepted = False
if Ptrial < Ptest:
Psi = trialPsi
XYZ = trialXYZ
Accepted = True
if i>N2ignore:
r2save = XYZ
if not Accepted:
r2save = genNewXYZ(XYZ, dxyz)
outf.write(" %15.10f %15.10f %15.10f %15.5e\n" % tuple(list(r2save)+[Psi]))
if Psi > 0.0:
outfp.write(" %15.10f %15.10f %15.10f %15.5e\n" % tuple(list(r2save)+[Psi]))
else:
outfn.write(" %15.10f %15.10f %15.10f %15.5e\n" % tuple(list(r2save)+[Psi]))
:
Python
import numpy as np
import random as rnd
DXYZ = 0.5
dxyz = 0.1*DXYZ
def getWFN(R, a=1.0, b=0.5, X0=0.2, Y0=0.5, Z0=0.2):
if R[1]<0.:
return (a*(R[1])**3 + b*R[1])*np.exp(-np.abs(R[0])/X0 - np.abs(R[1])/Y0 - np.abs(R[2])/Z0)
else:
return 0.0
Npts = 20000
N2ignore = Npts/10
outf = open("body.dat", "w")
genNewXYZ = lambda xyz, shift: xyz + np.array([rnd.uniform(-shift,shift) for q in range(0,3)])
XYZ = np.array([0.0,-0.2,0.0])
Psi = getWFN(XYZ, DXYZ)
for i in range(0,Npts):
trialXYZ = genNewXYZ(XYZ, DXYZ)
trialPsi = getWFN(trialXYZ)
if i % N2ignore == 0:
print("step #%i" % (i))
Ptrial = rnd.random()
Ptest = trialPsi**2/Psi**2
Accepted = False
if Ptrial < Ptest:
Psi = trialPsi
XYZ = trialXYZ
Accepted = True
if i>N2ignore:
r2save = XYZ
if not Accepted:
r2save = genNewXYZ(XYZ, dxyz)
outf.write(" %15.10f %15.10f %15.10f %15.5e\n" % tuple(list(r2save)+[Psi]))
, s-:
Python
import numpy as np
import random as rnd
DXYZ = 0.9
dxyz = 0.1*DXYZ
def getWFN(R, a=1.0, b=0.5, X0=0.3, Y0=0.5, Z0=0.3):
return np.exp(-np.abs(R[0])/X0 - np.abs(R[1])/Y0 - np.abs(R[2])/Z0)
Npts = 10000
N2ignore = Npts/10
outf = open("head.dat", "w")
genNewXYZ = lambda xyz, shift: xyz + np.array([rnd.uniform(-shift,shift) for q in range(0,3)])
XYZ = np.array([0.0,-0.2,0.0])
Psi = getWFN(XYZ, DXYZ)
for i in range(0,Npts):
trialXYZ = genNewXYZ(XYZ, DXYZ)
trialPsi = getWFN(trialXYZ)
if i % N2ignore == 0:
print("step #%i" % (i))
Ptrial = rnd.random()
Ptest = trialPsi**2/Psi**2
Accepted = False
if Ptrial < Ptest:
Psi = trialPsi
XYZ = trialXYZ
Accepted = True
if i>N2ignore:
r2save = XYZ
if not Accepted:
r2save = genNewXYZ(XYZ, dxyz)
outf.write(" %15.10f %15.10f %15.10f %15.5e\n" % tuple(list(r2save)+[Psi]))
, , :
Python
import numpy as np
import random as rnd
DXYZ = 0.9
dxyz = 0.1*DXYZ
def getWFN(R, a=1.0, b=0.5, X0=0.4, Y0=0.68, Z0=0.3):
if R[1]<0.:
return (a*(R[1])**3 + b*R[1])*np.exp(-np.abs(R[0])/X0 - np.abs(R[1])/Y0 - np.abs(R[2])/Z0)
else:
return 0.0
Npts = 1000
N2ignore = Npts/10
outf = open("body_fire.dat", "w")
genNewXYZ = lambda xyz, shift: xyz + np.array([rnd.uniform(-shift,shift) for q in range(0,3)])
XYZ = np.array([0.0,-0.2,0.0])
Psi = getWFN(XYZ, DXYZ)
for i in range(0,Npts):
trialXYZ = genNewXYZ(XYZ, DXYZ)
trialPsi = getWFN(trialXYZ)
if i % N2ignore == 0:
print("step #%i" % (i))
Ptrial = rnd.random()
Ptest = trialPsi**2/Psi**2
Accepted = False
if Ptrial < Ptest:
Psi = trialPsi
XYZ = trialXYZ
Accepted = True
if i>N2ignore:
r2save = XYZ
if not Accepted:
r2save = genNewXYZ(XYZ, dxyz)
outf.write(" %15.10f %15.10f %15.10f %15.5e\n" % tuple(list(r2save)+[Psi]))
(xn, yn, zn, ψn) n=0,1,2,..., . Gnuplot multiplot. (set view map). , : https://github.com/Gnuplotting/gnuplot-palettes.
inferno, — ylrd, . - : plasma, parula, — prgn.
Plasma — , - , . Parula , , ... , , , . prgn, : , , . Inkscape .
Gnuplot
#set terminal pngcairo size 1500,1500 transparent
set terminal pngcairo size 1500,1500 background rgb '#080045'
set output "ff_v2.png"
set multiplot
set view map
set size ratio 1
unset colorbox
unset border
unset key
unset xtics
unset ytics
XMax = 7.
set xrange [-XMax:XMax]
set yrange [-XMax:XMax]
set pm3d depthorder hidden3d 1
set hidden3d
set style fill transparent solid 0.35 noborder
set style circle radius 0.02
load 'prgn.pal'
#load 'plasma.pal'
#load 'parula.pal'
splot 'wfn_pos.dat' u 2:1:3:4 w p pt 7 ps 2 lc palette
splot 'wfn_neg.dat' u 2:1:3:4 w p pt 7 ps 2 lc palette
load 'inferno.pal'
splot 'body.dat' u 1:2:3:4 w l lc palette
splot 'head.dat' u 1:2:3:4 w l lc palette
load 'ylrd.pal'
splot 'body_fire.dat' u 1:2:3:(-$4) w l lw 3 lc palette
P.S.
, - , . , , YouTube .