Translate

niedziela, 13 maja 2012

26. Algorytmy rysowania orbitali

    Orbital to funkcja. Orbital, to ładna nazwa dla funkcji. Podobnie ładne nazwy, to np. sinus albo tangens. Te ostatnie funkcje opisują na przykład ruch punktu w obiekcie, który drga. Fizycy umówili się, że orbital opisuje zachowanie się elektronu w atomie lub cząsteczce związku chemicznego. Słowo orbital kojarzy się z orbitą, ale zachowanie się elektronu opisywane przez orbital jest o wiele bardziej niezwykłe, niż zachowanie się komety Halleya na orbicie okołosłonecznej. Jeżeli orbital jest funkcją, to powinniśmy umieć narysować jej wykres. Kłopot polega na tym, że wykres taki zajmuje CAŁĄ dostępną przestrzeń fizyczną. Nie możemy narysować wykresu orbitalu, bo o wartości tej funkcji należą do czwartego wymiaru geometrycznego.

    Na pytanie - co widzimy w książkach, gdy patrzymy na kształty orbitali - odpowiadam - że widzimy przekroje orbitali, a nie wykresy. Różnicę między pojęciem wykresu i przekroju najlepiej wyjaśnić na przykładzie atlasu geograficznego. Jeśli kształt góry albo rowu morskiego określimy, jako wykres, to warstwice na kartce papieru będą odpowiednikiem przekrojów przy ustalonej (my to ustalamy!) wartości wysokości nad poziomem morza. Czyli w celu narysowania przekroju orbitalu należy ustalić wartość liczbową, przy której będziemy stawiać punkty przekroju.

    Podstawową przeszkodą w upowszechnieniu umiejętności precyzyjnego rysowania przekrojów orbitali za pomocą komputerów, jest przekonanie, że odpowiednie rysunki można uzyskać jedynie za pomocą programów dysponujących zaawansowanymi procedurami graficznymi i obliczeniowymi. Jest tak zapewne, gdy żądamy narysowania trójwymiarowych przekrojów. W wypadku przekrojów na płaszczyźnie dwuwymiarowej sytuacja jest o wiele prostsza. Należy dysponować podstawowymi umiejętnościami stosowania języków programowania oraz właściwie zdefiniowanym zadaniem.

    Sięgniemy do języka programowania, jakim jest Small Basic oraz QBASIC. Mam nadzieję, że narzędzie to ma jeszcze zwolenników. Prostota struktury, całkiem sensowny interfejs użytkownika i niewyszukane instrukcje powodują, że QBASIC jest... wymagający. A tak! Wymaga takiego opracowania procedur obliczeniowych, aby dały się przedstawić w możliwie prosty sposób i liczyły się szybko. To jest zadanie dla dydaktyki.

    Procedura rysowania orbitalu jest stosunkowo prosta. Najpierw wybieramy funkcję, np.
psi = a*exp(-c*r).
Wielkości a oraz c to stałe, r to promień wodzący elektronu. Gdy stałe odpowiednio dobierzemy, to znaczy, że rozpatrujemy orbital 1s atomu wodoru. Gdy dobierzemy nieodpowiednio, to później możemy się oczywiście poprawić zmieniając pierwotne liczby na właściwe. Teraz ustalamy rozsądną wartość psi, obliczamy w każdym punkcie (może nie w każdym, ale w wielu) przestrzeni wartość orbitalu. Punkt, dla którego wartość funkcji jest większa od przyjętej liczby (zmienna kontur) malujemy na ekranie monitora. Tak powstaje kontur orbitalu. Dwuwymiarowy przekrój orbitalu 1s realizuje poniższy program, napisany w języku Small Basic. Program składa się ze sporej liczby linijek, ale wystarczy chwilę przyjrzeć się jego treści, aby dostrzec, że większą część wydruku zajmują dane i instrukcje rysowania punktów na ekranie. Fragment obliczeniowy znajduje się w środku zewnętrznej pętli For...EndFor. Wydaje mi się, że jego skomplikowanie nie jest zbyt duże.

'program orbital 1s, contour plotting
'Author, Wojciech Szczepankiewicz. Silesian University of Technology
'Gliwice, Poland
'Start of BlockData
    GraphicsWindow.BackgroundColor="Black"
    e = 2.7182818 'Natural log base
    scale = 50
    trans_x = 320
    trans_y = 200
    psi_value = .123
    start_x = -2.5
    end_x = 2.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)
    orbital_1s = math.Power(e, -radius)
     If orbital_1s >= psi_value Then
        x_screen = x * scale + trans_x
        y_screen = y * scale + trans_y
        GraphicsWindow.SetPixel(x_screen, y_screen, "Blue")
     EndIf
  EndFor
EndFor
GraphicsWindow.DrawText(10,400,"End of plot")
Działanie programu można zobaczyć na stronie Small Basica. Wynikiem działania programu jest po prostu koło. W jego wnętrzu wartość orbitalu jest większa od przyjętej w zmiennej orbital_1s.
    Proszę wykonać kilka eksperymentów z programem i odkryć, jak wpływa wartość zmiennej kontur na promień koła. Łatwo jest pokazać, że program po niewielkich modyfikacjach może namalować inne orbitale. Proszę przeanalizować poniższy program.

'-------------- poczatek danych
skala = 50
ustawx = 300
ustawy = 230
kontur = .125
startx = -4
koniecx = 4
starty = -4
koniecy = 4
boksiatki = .02
'-------------- koniec danych
screen 12
for x = startx to koniecx step boksiatki
   for y = starty to koniecy step boksiatki
      promien = sqr(x * x + y * y)
      orbital = x * exp(-promien)
      'orbital = y * exp(-promien)
      xekran = x * skala + ustawx
      yekran = y * skala + ustawy
      if orbital >= kontur then pset (xekran, yekran), 3
      if orbital <= -kontur then pset (xekran, yekran), 5
   next y
next x

    Program generuje rysunek, przedstawiony poniżej. Proszę poeksperymentować z wartościami zmiennych a, c oraz kontur i zbadać, jak wpływają na postać przekroju. Orbital 2py można uzyskać przez usunięcie apostrofu sprzed odpowiednio zdefiniowanej zmiennej 'orbital'.
    Proszę sprawdzić, co się stanie, gdy we wzorze na zmienną orbital wstawimy y zamiast x.
Teraz narysujemy wybrane orbitale d. Program jest prawie taki sam, jak poprzednie. Zmiany dotyczą jedynie parametrów wyświetlania na ekranie i oczywiście wzoru definiującego orbital.
'-------------- poczatek danych
skala = 50
ustawx = 300
ustawy = 230
kontur = .125
startx = -3.7
koniecx = 3.7
starty = -4
koniecy = 4
boksiatki = .02
a = 1: c = 1
'-------------- koniec danych
screen 12
for x = startx to koniecx step boksiatki
   for y = starty to koniecy step boksiatki
      promien = sqr(x * x + y * y)
      orbital = a * x * y * exp(-c * promien)
      xekran = x * skala + ustawx
      yekran = y * skala + ustawy
      if orbital >= kontur then pset (xekran, yekran), 3
      if orbital <= -kontur then pset (xekran, yekran), 5
   next y
next x

    Poniżej kopia ekranu z rysunkiem orbitalu.

Orbital 3dz2-r2 wymaga pewnego komentarza. Taki orbital powinien być prostopadły do ekranu, ale jeśli umówimy się, że oś y będzie tymczasowo "podstawiać" oś z, to otrzymamy odpowiedni rysunek. Program jest prawie taki, jak poprzednio.
'-------------- poczatek danych
skala = 27
ustawx = 300
ustawy = 230
kontur = .125
startx = -5.4
koniecx = 6
starty = -7
koniecy = 7
boksiatki = .06
a = 1: c = 1
'-------------- koniec danych
screen 12
for x = startx to koniecx step boksiatki
  for y = starty to koniecy step boksiatki
    promien = sqr(x * x + y * y)
    orbital = a * (3 * y ^ 2 - promien ^ 2) * exp(-c * promien)
      xekran = x * skala + ustawx
      yekran = y * skala + ustawy
    if orbital >= kontur then pset (xekran, yekran), 3
    if orbital <= -kontur then pset (xekran, yekran), 5
  next y
 next x
    A wynik jego działania pokazuje przekroje dwóch "hantli" otoczonych pierścieniem.

    Wydawałoby się, że o rysowaniu przekrojów obitali wiemy już sporo. Okazuje się jednak, orbitale skonstruowane są tak, iż możliwy jest jeszcze jeden sposób rysowania ich przekrojów. Sposób ten jest niezwykle szybki nawet dla bardzo wolnych komputerów, ale tę szybkość uzyskuje się kosztem straty części informacji o orbitalu. Chodzi o tę część postaci matematycznej funkcji falowej, która jest zależna od promienia wodzącego. Wystarczy nieco uważniej przyjrzeć się rozpatrywanym powyżej funkcjom p albo d, aby zauważyć, iż zawierają czynniki zależne od współrzędnych oraz od promienia. Generalnie rzecz biorąc, orbitale można przedstawić w postaci iloczynów obu części. Jeœli pominiemy część zależną od promienia, to pozostają tylko funkcje współrzędnej x (np. orbital 2px) lub y, albo obu jednocześnie (np. orbital 3dxy). Oczywiście, dla orbitali w przestrzeni trójwymiarowej należy dołączyć fragmenty pochodzące od współrzędnej z, ale przypominam, iż my zajmujemy się tylko przekrojami leżącymi w płaszczyŸnie xy.    
    Rysowanie części kątowych orbitali jest pomysłowe. Wyobraźmy sobie prostokątny układ współrzędnych na płaszczyźnie xy. Przez początek układu niech przechodzi prosta o pod kątem teta do osi x. Na tej prostej odłożymy odcinek o długości określonej przez wartość części kątowej orbitalu. Na płaszczyźnie xy część kątowa wybranego orbitalu zależy tylko od kąta teta (w przestrzeni trójwymiarowej od jeszcze jednego kąta oznaczanego zwyczajowo fi). To jest dość pogmatwany wywód, ale stanie się bardziej przyjazny, gdy rozważymy konkretny orbital (oczywiście pozbawiony stosowanych stałych). Niech to będzie orbital 2px. Przypomnijmy jego postać matematyczną: orbital = x*EXP(-promien).
Pominięcie części zależnej od promienia prowadzi do bardzo prostego wzoru:
orbital = x
Nie pomyliło się coś autorowi? Zapewniam, że nie! Tę zwykłą zmienną x można tak zastosować, żeby odtworzyła przybliżoną postać omawianego orbitalu. Potrzebujemy w tym celu nieco trygonometrii. Współrzędna x jakiegoœ punktu prostej przechodzącej pod kątem teta do osi OX wynosi cos(teta) (podobnie jak współrzędna = sin(teta)). Po tej drobnej modyfikacji część kątowa przyjmie postać:
orbital = cos(teta)
    Tę wartość orbitalu odłożymy na anonsowanej już prostej. Trzeba uważać, żeby się nie pomylić, bo na prostej wyznaczonej przez kąt teta odkładamy odcinek wyznaczony przez kosinus tego kąta. Koniec odłożonego odcinka wyznacza punkt części kątowej, który to punkt należy narysować na ekranie monitora. Ale skoro tak, to powstaje pytanie, jakie są współrzędne (x,y) końca odłożonego odcinka. Wypadałoby poinformować komputer, w którym miejscu ekranu ma zapalić punkt świetlny. Ponownie odwołujemy się do wprowadzonej przed chwilą odrobiny trygonometrii. Wzory na współrzędne x oraz y części kątowej orbitalu 2px mają ostatecznie postać:
x = abs(orbital)*cos(teta)
y = abs(orbital)*sin(teta)
Koniecznie należy wyjaśnić, dlaczego ze zmiennej "orbital" wyciąga się wartość bezwzględną. Ta zmienna reprezentuje tu długość odcinka, a długość odcinka nie może być wartością ujemną. W tym cała tajemnica. Czas na program, dzięki któremu uzyskamy odpowiedni rysunek. Zastosujemy ponownie "QBASIC". Poniższy, niewielki program jest tak prymitywny, że poznany uprzednio program musi się wydać niezwykle zaawansowanym narzędziem w porównaniu do wydruku pokazanego poniżej, który umożliwia narysowanie częœci kątowych orbitali 2p oraz 3d.

'program rysuje części kątowe orbitali
pix2 = 2 * 3.1415
skala = 100
ustawx = 300
ustawy = 220
a = 1: b = 2
screen 12
for teta = 0 to pix2 step .001
  'orbital = a * (sin(teta))            '2p
  'orbital = a * cos(teta)              '2px
  'orbital = a * sin(teta) * cos(teta)  '3dxy
   orbital = a * cos(teta) ^ 2 - b * sin(teta) ^ 2'3dx^2-y^2
  x = abs(orbital) * cos(teta)
  y = abs(orbital) * sin(teta)
  xe = skala * x + ustawx
  ye = skala * y + ustawy
  pset (xe, ye)
next teta

    W celu uzyskania rysunku innego orbitalu wystarczy usunąć apostrof sprzed definicji zmiennej orbital. Podobnie, jak w poprzednich przykładach proszę o sprawdzenie wpływu zmiennych oraz b na kształt obitali.

Brak komentarzy :

Prześlij komentarz