KodHTML

czwartek, 20 lutego 2020

Zebrane procedury rysowania przekrojów orbitali atomowych

Poniżej zebrałem procedury, które rysują przekroje orbitali atomowych. Interesowało mnie kiedyś, jak to zrobić, ale nie umiałem znaleźć w podręcznikach odpowiednich programów komputerowych. Dzięki temu, że nauczyłem się podstaw programowania na Wydziale Chemicznym Politechniki Śląskiej, byłem w stanie sam takie programiki napisać. W tamtym czasie używałem języka QBASIC. W wydaniu poniżej jest to Small Basic. W procedurach usunąłem wszelkie stałe, które zaciemniają wzory użyte do obliczeń. Zawsze można te stałe dodać, wówczas zmienią się niektóre proporcje rysunków, ale generalnie obraz pozostanie taki sam.

Pierwszy jest orbital (a właściwie jego część kątowa) 3dz2:
Procedura, która znajduje się poniżej umożliwia również narysowanie części kątowych innych orbitali. Wystarczy tylko usunąć znak komentarza (apostrof) przed odpowiednimi wzorami:

'program  - Angle part of 2p or 3d orbitals written originally in 1994 (QBASIC)
'Author, Wojciech Szczepankiewicz. Silesian University of Technology
'Gliwice, Poland
'Start of BlockData
    GraphicsWindow.BackgroundColor="White"
    pi2= 2*Math.Pi
    scale = 100
    trans_x = 320
    trans_y = 210    
'End of BlockData
    
' Main part 
For theta = 0 To pi2 Step 0.001
    'psi = math.Cos(theta)    'orbital 2px
    'psi=math.Sin(theta)       'orbital 2py
    'psi=math.Sin(theta)*math.Cos(theta)   'orbital 3dxy
    'below - orbital 3dz2
    psi=math.Cos(theta)* math.Cos(theta)-2*math.Sin(theta)*math.Sin(theta)
    'Calculation of cartesian coordinates from angle data
    x = math.Abs(psi)*math.Cos(theta)
    y = math.Abs(psi)*math.Sin(theta)
    'Fitting screen coordinates
    x_screen = x * scale + trans_x
    y_screen = y * scale + trans_y
    'Plotting set of points
    GraphicsWindow.SetPixel(x_screen, y_screen, "Black")
EndFor
GraphicsWindow.DrawText(10,400,"End of plot")

Orbital 2px z rozróżnioną za pomocą kolorów częścią dodatnią i ujemną. Kolor niebieski pokazuje część dodatnią, a czerwony ujemną:
'program orbital 2px, contour plotting
'Author, Wojciech Szczepankiewicz. Silesian University of Technology
'Gliwice, Poland
'Start of BlockData
    GraphicsWindow.BackgroundColor="White"
    e = 2.7182818 'Natural log base
    scale = 50
    trans_x = 320
    trans_y = 200
    psi_value = .123
    start_x = -10.5
    end_x = 10.5
    start_y = -5
    end_y = 5
    net_step = .02
'End of BlockData
' Main part 
For x = start_x To end_x Step net_step
  For y = start_y To end_y Step net_step
    radius = math.SquareRoot(x * x + y * y)
 100   orbital_2p = x*math.Power(e, -radius)   'change 'x' on 'y'
     If orbital_2p >= psi_value Then
        x_screen = x * scale + trans_x
        y_screen = y * scale + trans_y
        GraphicsWindow.SetPixel(x_screen, y_screen, "Blue")
      EndIf
     If orbital_2p <= -psi_value Then
        x_screen = x * scale + trans_x
        y_screen = y * scale + trans_y
        GraphicsWindow.SetPixel(x_screen, y_screen, "Red")
     EndIf 
  EndFor
EndFor
GraphicsWindow.DrawText(10,400,"End of plot")

W celu uzyskania orbitalu 2py wystarczy w wierszu 100 zmienić zmienną x na y.

Orbital 2s uzyskuje się w analogiczny sposób, tyle że funkcja orbitalowa jest inna, ale niezbyt skomplikowana. Rysunek poniżej pokazuje wynik działania odpowiedniego programu:



'program orbital 2s, contour plotting
'Author, Wojciech Szczepankiewicz. Silesian University of Technology
'Gliwice, Poland
'Start of BlockData
    GraphicsWindow.BackgroundColor="White"
    e = 2.7182818 'Natural log base
    scale = 30
    trans_x = 320
    trans_y = 200
    psi_value = .02
    start_x = -9.0
    end_x = 9.0
    start_y = -5.0
    end_y = 5.0
    net_step = .02
'End of BlockData
' Main part 
For x = start_x To end_x Step net_step
  For y = start_y To end_y Step net_step
    radius = math.SquareRoot(x * x + y * y)
    orbital_2s = (2-radius)*math.Power(e, -radius)
     If orbital_2s >= psi_value Then
        x_screen = x * scale + trans_x
        y_screen = y * scale + trans_y
        GraphicsWindow.SetPixel(x_screen, y_screen, "Blue")
      EndIf
     If orbital_2s <= -psi_value Then
        x_screen = x * scale + trans_x
        y_screen = y * scale + trans_y
        GraphicsWindow.SetPixel(x_screen, y_screen, "Red")
     EndIf 
  EndFor
EndFor
GraphicsWindow.DrawText(10,400,"End of plot")

Powinienem zacząć od tego orbitalu, mianowicie 1s, ale niech nie będzie takie to wszystko ułożone. Program daje rysunek koła. Jrst ono niebieskie, gdyż wszystkie wartości tego orbitalu są nieujemne:

'Początek bloku danych dla orbitalu 1s
GraphicsWindow.BackgroundColor="White"
e = 2.7182818 'Podstawa logarytmu naturalnego
scale = 50    'Dopasowanie wielkości rysunku do ekranu
'Ustalenie początku ukł. współrzędnych względem narożnika ekranu
trans_x = 320 
trans_y = 200 
psi_value = .123 'Przyjęta wartość orbitalu 1s 
start_x = -2.5   'Współrzędna x początku przeszukiwania obszaru
end_x = 2.5      'Współrzędna x końca przeszukiwania obszaru
start_y = -5     'Współrzędna y początku przeszukiwania obszaru
end_y = 5        'Współrzędna y końca przeszukiwania obszaru
net_step = .02   'Krok siatki przeszukiwania
'Koniec bloku danych

'Pętla główna    
For x = start_x To end_x Step net_step
  For y = start_y To end_y Step net_step
    'Obl. promienia wodzącego elektronu
    radius = math.SquareRoot(x * x + y * y)
    'Obl. wartości funkcji psi 
    orbital_1s = math.Power(e, -radius)
     'Warunek postawienia punktu na ekranie 
     If orbital_1s >= psi_value Then 
        x_screen = x * scale + trans_x
        y_screen = y * scale + trans_y
        'Rysowanie punktu na ekranie
        GraphicsWindow.SetPixel(x_screen, y_screen, "Blue") 
     EndIf
  EndFor
EndFor

Kolejny to przekrój orbitalu 3dxy. Przekrój na płaszczyźnie xy tworzy cztery "gałęzie" pomiędzy  osiami x oraz y:
'program orbital 3dxy, contour plotting
'Author, Wojciech Szczepankiewicz. Silesian University of Technology
'Gliwice, Poland
'Start of BlockData
    GraphicsWindow.BackgroundColor="White"
    e = 2.7182818 'Natural log base
    scale = 50
    trans_x = 320
    trans_y = 200
    psi_value = .123
    start_x = -9.0
    end_x = 9.0
    start_y = -5
    end_y = 5
    net_step = .02
'End of BlockData
' Main part 
For x = start_x To end_x Step net_step
  For y = start_y To end_y Step net_step
    radius = math.SquareRoot(x * x + y * y)
    orbital_3dxy = x*y*math.Power(e, -radius)
     If orbital_3dxy >= psi_value Then
        x_screen = x * scale + trans_x
        y_screen = y * scale + trans_y
        GraphicsWindow.SetPixel(x_screen, y_screen, "Blue")
      EndIf
     If orbital_3dxy <= -psi_value Then
        x_screen = x * scale + trans_x
        y_screen = y * scale + trans_y
        GraphicsWindow.SetPixel(x_screen, y_screen, "Red")
     EndIf 
  EndFor
EndFor
GraphicsWindow.DrawText(10,400,"End of plot")

Orbital 3dx2y2 jest podobny do powyższego, ale jego "gałęzie" znajdują się na osiach i oraz y. Nie daję rysunku, a jedynie tekst programu poniżej:

'program orbital 3dx2-y2, contour plotting
'Author, Wojciech Szczepankiewicz. Silesian University of Technology
'Gliwice, Poland
'Start of BlockData
    GraphicsWindow.BackgroundColor="Black"
    e = 2.7182818 'Natural log base
    scale = 30
    trans_x = 320
    trans_y = 200
    psi_value = .123
    start_x = -8.0
    end_x = 8.0
    start_y = -8
    end_y = 8
    net_step = .02
'End of BlockData
' Main part 
For x = start_x To end_x Step net_step
  For y = start_y To end_y Step net_step
    radius = math.SquareRoot(x * x + y * y)
    orbital_3dx2y2 = (x*x-y*y)*math.Power(e, -radius)
     If orbital_3dx2y2 >= psi_value Then
        x_screen = x * scale + trans_x
        y_screen = y * scale + trans_y
        GraphicsWindow.SetPixel(x_screen, y_screen, "Blue")
      EndIf
     If orbital_3dx2y2 <= -psi_value Then
        x_screen = x * scale + trans_x
        y_screen = y * scale + trans_y
        GraphicsWindow.SetPixel(x_screen, y_screen, "Red")
     EndIf 
  EndFor
EndFor
GraphicsWindow.DrawText(10,400,"End of plot")

Wracam teraz do pierwszego orbitalu, czyli 3dz2, ale w pełnej wersji, czyli razem z częścią radialną:
'program orbital 3dz2, contour plotting
'Author, Wojciech Szczepankiewicz. Silesian University of Technology
'Gliwice, Poland
'Start of BlockData
    GraphicsWindow.BackgroundColor="White"
    e = 2.7182818 'Natural log base
    scale = 30
    trans_x = 320
    trans_z = 220
    psi_value = .123
    start_x = -8.0
    end_x = 8.0
    start_z = -8
    end_z = 8
    net_step = .02
'End of BlockData
' Main part 
For x = start_x To end_x Step net_step
  For z = start_z To end_z Step net_step
    radius = math.SquareRoot(x * x + z * z)
    orbital_3dz2 = (3*z*z-radius*radius)*math.Power(e, -radius)
     If orbital_3dz2 >= psi_value Then
        x_screen = x * scale + trans_x
        y_screen = z * scale + trans_z
        GraphicsWindow.SetPixel(x_screen, y_screen, "Blue")
      EndIf
     If orbital_3dz2 <= -psi_value Then
        x_screen = x * scale + trans_x
        y_screen = z * scale + trans_z
        GraphicsWindow.SetPixel(x_screen, y_screen, "Red")
     EndIf 
  EndFor
EndFor
GraphicsWindow.DrawText(10,400,"End of plot")

Orbitale można również rysować z użyciem współrzędnych biegunowych. Rysunki te wykazują jednak pewną wadę. Im dalej od jągra, tym punktów jest mniej. Tym niemniej i taki sposób rysowania jest możliwy. Poniżej przekrój orbitalu 3s:
'program orbital 3s, contour plotting in polar coordinates
'Author, Wojciech Szczepankiewicz. Silesian University of Technology
'Gliwice, Poland
'Start of BlockData
    GraphicsWindow.BackgroundColor="White"
    e = 2.7182818 'Natural log base
    scale = 40
    trans_x = 320
    trans_z = 220
    psi_value = .123
    radius_end = 5
    radius_step = 0.01
    phi_step=0.01
'End of BlockData
' Main part 

For phi = 0 To 2*Math.pi Step phi_step
  For radius = 0 To radius_end Step radius_step
    orbital_3s = (6-6*radius-6*radius*radius)*math.Power(e, -radius)
     If orbital_3s >= psi_value Then
        x_screen = (radius*Math.cos(phi)) * scale + trans_x
        y_screen = (radius*Math.sin(phi)) * scale + trans_z
        GraphicsWindow.SetPixel(x_screen, y_screen, "Blue")
      EndIf
     If orbital_3s <= -psi_value Then
       x_screen = (radius*Math.cos(phi)) * scale + trans_x
        y_screen = (radius*Math.sin(phi)) * scale + trans_z
        GraphicsWindow.SetPixel(x_screen, y_screen, "Red")
     EndIf 
  EndFor
EndFor
GraphicsWindow.DrawText(10,400,"End of plot")




czwartek, 6 lutego 2020

Przykładowa hybryda orbitali atomowych

   Hybrydyzacja to procedura matematyczna, której użył Linus Pauling do wyjaśnienia wyznaczonych doświadczalnie kątów między wiązaniami w prostych cząsteczkach np. metanu, etenu, wody czy amoniaku. Hybrydyzacja to procedura sumowania orbitali, czyli dodawania (i odejmowania oczywiście) funkcji. Zrobił to bo orbitale 2s i 2p dawały dziwaczny obraz wiązań w tych cząsteczkach. Sumy orbitali odtwarzały rozsądnie dane doświadczalne. Jak się sumuje funkcje. Zupełnie prosto. Bierzemy dwie (albo więcej) funkcji i dodajemy je do siebie. Czasem mnożymy je przez współczynniki. To wszystko.
   Zrealizujmy praktycznie dodawanie funkcji 2s oraz 2px, ale z pominięciem współczynników, które są konieczne w obliczeniach szczegółowych, ale zaciemniają istotę zagadnienia. Wynik i tak będzie sensowny. Dodawanie realizują programy, których wydruki są na końcu tego wpisu zamieszczony poniżej.

   Wynik działania programu z zaznaczeniem na fioletowo części ujemnej orbitalu, a na kolor niebieski części dodatniej.
   Proszę o dokonanie doświadczeń z mnożeniem poszczególnych orbitali przez współczynniki, aby zorientować się, co do wpływu wartości tych stałych na kształt hybrydy. Proszę sprawdzić, jak wpływa usunięcie apostrofu sprzed zmiennej orbital3 na orientację "hantli" hybrydy. Czy powstanie wtedy jedno z ramion hybrydy sp2? Jeszcze tylko małe usprawiedliwienie. Wybrałem hybrydę sp, dlatego że bez żadnych kłopotów daje się narysować na płaszczyźnie ekranu. Podobnie jest z hybrydą sp2. Inne hybrydy rozmieszczone są często między osiami (np. hybryda sp3). Rysowanie przekrojów w jednej płaszczyźnie daje mocno zubożony obraz takiej funkcji. W celu uzyskania poprawnych obrazów należy stosować przekroje trójwymiarowe.

Starsza wersja programu w QBASICu:
'-------------- poczatek danych
skala = 45
ustawx = 300
ustawy = 230
kontur = .15
startx = -4.2
koniecx = 3.2
starty = -4.2
koniecy = 4.2
boksiatki = .02
'-------------- koniec danych
screen 12
for x = startx to koniecx step boksiatki
   for y = starty to koniecy step boksiatki
     r = sqr(x * x + y * y)
     orbital1 = (2 - r) * exp(-r)
     orbital2 = x * exp(-r)
     'orbital3 = y * exp(-r)
     hybryda = orbital1 + orbital2 '+ orbital3
     xekran = x * skala + ustawx
     yekran = y * skala + ustawy
     if hybryda >= kontur then pset (xekran, yekran), 3
     if hybryda <= -kontur then pset (xekran, yekran), 5
   next y
next x

Nowsza wersja (2020) programu w SmallBasicu:
dane()
for x = startx to koniecx step boksiatki
   for y = starty to koniecy step boksiatki
     r = Math.SquareRoot(x * x + y * y)
     orbital1 = (2 - r) * Math.Power(exp, -r)
     orbital2 = x * Math.Power(exp, -r)
     'orbital3 = y * Math.Power(exp, -r)
     hybryda = orbital1 + orbital2 '+ orbital3
     xekran = x * skala + ustawx
     yekran = y * skala + ustawy
     if hybryda >= kontur then
        GraphicsWindow.SetPixel(xekran, yekran, "blue")
       ElseIf hybryda <= -kontur then
        GraphicsWindow.SetPixel(xekran, yekran, "magenta")
       EndIf  
   EndFor 
  EndFor
 
Sub dane
 skala = 45
 ustawx = 300
 ustawy = 230
 kontur = .15
 startx = -4.2
 koniecx = 3.2
 starty = -4.2
 koniecy = 4.2
 boksiatki = .02
 exp = 2.71
EndSub

   

Miałem kiedyś taki pomysł nomenklaturowy, ale mi przeszło (2016)

Propozycja wprowadzenie przedrostka dvo dla kompaktowego określania obecności dwóch różnych podstawników w cząsteczce związku organicznego

Wojciech Szczepankiewicz
Department of Organic Chemistry, Biochemistry and Biotechnology
Silesian University of Technology
Krzywoustego 4
44-100 Gliwice
Poland

Introduction

W pewnych sytuacjach nazewniczych pojawiają się niejednoznaczności ze ścisłym określeniem nazw związków, w których chcemy za pomocą jednego przedrostka określić dwa różne podstawniki podłączone do tej samej cząsteczki macierzystej. Naturalne wydaje się dodanie przedrostka di do wyrazu „podstawionego”. Jednakże taka praktyka rozszerza zakres stosowalności przedrostka di (i ewentualnie bis) na różne podstawniki w sposób niezgodny z założonym znaczeniem, gdyż przedrostki te określają jednakowe podstawniki. Tym niemniej praktyka ta jest stosowana stosunkowo często do kompaktowego określenia dwu różnych podstawników np. w pirolidynach [1,2] benzopiranach [3] laktonach [4], poliacetylenach [5] i w wielu innych przykładach.

Proposition

W celu zwiększenia kompaktowości i poprawienia komunikatywności zapisu, proponuję wprowadzić przedrostek dvo dla określenia sytuacji ogólnej, w której chcemy opisać dwa różne podstawniki za pomocą jednego przedrostka, ale bez konieczności określania ścisłego charakteru tych podstawników. W tym kontekście przedrostek ten jest nadrzędny w stosunku do przedrostka di oraz bis i zawiera ich definicje.
Przedrostek dvo jest charakterystyczny dla niektórych języków słowiańskich i oznacza podwojenie. Wydaje się on łatwy do wypowiedzenia, krótki i niezbyt odbiegający od przedrostka di, choć wystarczająco różny, aby oba przedrostki nie były mylone podczas słuchania wypowiedzi słownych.

Examples

W kontekście przytoczonej literatury należałoby mówić dvopodstawionych pirolidynach, dvopodstawionych benzopiranach itd. W sytuacji, gdy różne podstawniki należą do jednego szeregu homologicznego, albo należą do jednej klasy związków można zasadę uściślić i mówić np. o dvoalkilowanych benzenach (1-etylo-3-metylobenzen), albo dvoalkoksylowanych polieterach, itp. Przykłady można mnożyć.

Caution

            Nie wydaje mi się konieczne rozszerzanie tego typu nazewnictwa na trzy i większą liczbę podstawników, że względu na wzrost liczby możliwych kombinacji nazewniczych, np: trzy różne podstawniki albo dwa jednakowe i jeden inny. Albo dla czterech podstawników: cztery różne, trzy jednakowe-jeden inny, albo po dwa jednakowe. Te sytuacje powinny być regulowane dotychczasowymi ustaleniami IUPAC.

Conclusion

Zastosowanie przedrostka dvo powoduje uściślenie tych sytuacji nomenklaturowych, które wymagają kompaktowego określania sytuacji, w której jest konieczne opisywanie wspólnego kontekstu nazewniczego dla dwu różnych podstawników w jednym związku chemicznym.

Literature

1. J. M. Schomaker, S. Bhattachrjee, J. Yan, B. Borthan, J. Am. Chem. Soc.,  
3. S. A. Worlikar, T. Kesharwani, T. Yao, R. C. Larock, J. Org. Chem., 
4. S. A. M. T. Hussain, W. D. Ollis, C. Smith, J. F. Stoddart, J. Chem. Soc., Chem. Comm.1974, 873-874.