How we pumped the conference logo with SciArt

Last year (2020), in connection with the pandemic, we held an online scientific conference on computational chemistry , and we made a logo for it, which was, to put it mildly, so-so. Below the cut is a story about how we pumped it for this (2021) conference using a small amount of quantum mechanics, the Monte Carlo method, Python and Gnuplot.





A bit of background

2020, the coronavirus is gaining momentum, restrictions are imposed, and to maintain the level of scientific discussion, improve scientific cooperation among Russian-speaking scientists scattered around the world, and for all the rest of the good, we organized a mini-symposium on computational chemistry online .





But what is a conference without a logo? And having gathered into a fist all the artistic (from the word "bad") possibilities of the organizing committee of the conference, a logo was created in Inkscape :





The original logo that we made with Inkscape and Jmol + Gimp (for drawing fullerenes).
The original logo that we made with Inkscape and Jmol + Gimp (for drawing fullerenes).

. , 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- :





\ psi (x, y, z) = x \ cdot y \ cdot \ exp (-r)

rr, , . , . , , :





\ psi (x, y, z) = (0.05 \ cdot y ^ 3 + 0.9 \ cdot x \ cdot y) \ cdot \ exp (-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]))
      
      



:





\ psi (x, y, z) = \ begin {cases} (y ^ 3 + 0.5 \ cdot y) \ cdot \ exp \ left (- \ frac {| x |} {0.2} - \ frac {| y | } {0.5} - \ frac {| z |} {0.2} \ right) \, \ y <0 \\ 0, \ y \ geq 0 \ end {cases}
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-:





\ psi (x, y, z) = \ exp \ left (- \ frac {| x |} {0.3} - \ frac {| y |} {0.5} - \ frac {| z |} {0.3} \ right )
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]))
      
      



, , :





\ psi (x, y, z) = \ begin {cases} (y ^ 3 + 0.5 \ cdot y) \ cdot \ exp \ left (- \ frac {| x |} {0.4} - \ frac {| y | } {0.68} - \ frac {| z |} {0.3} \ right) \, \ y <0 \\ 0, \ y \ geq 0 \ end {cases}
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 .








All Articles