Animacija fluida u okruženju s preprekama

FER >> ZEMRIS >> Racunalna grafika
SIMPLE
Vizualizacija

Programsko rješenje se sastoji od dvije temeljne klase (uz par pomoćnih). Klasa Solver je što se simulacije fluida tiče temelj programa. Sve metode koje se bave simulacijom ponašanja fluida, računanjem tlakova i brzina, iterativnim postupkom, provjeravanjem konvergencije i slično smještene su isključivo na ovom mjestu. Klasa Visualizer služi samo za vizualizaciju rezultata dobivenih korištenjem podataka i metoda u ovoj klasi. Ovdje je pojašnjenje metoda klase Solver.

Iteriranje glavne petlje algoritma

Jedina metoda koju je potrebno pozvati nakon što su zadane vrijednosti svih potrebnih parametara je advanceTimeStep(). Ova metoda vraća logičku vrijednost true u slučaju da je korak simulacije završio konvergencijom ili false ako do konvergencije nije došlo. Sama metoda samo poziva druge metode u slijedu koji u potpunosti prati algoritam SIMPLE. Izvorni kod je dan u nastavku.


      public bool advanceTimeStep ()
      {
            switchVelocities ();
           
            for (int iteracija = 0; iteracija < maxIteracija; iteracija++)
            {
                  calculateNewVelocities ();
                  calculatePCorrection ();
                  applyPCorrection ();
                  if (maxPCorrection < convergenceCondition)
                  {
                        applyVelocityCorrections ();
                        return true;
                  }
            }
      return false;
      }


U kodu su vidljivi koraci SIMPLE algoritma. Unutar for petlje se prvo računaju novi iznosi brzina (drugi korak algoritma), zatim se iteracijskim postupkom koji je u potpunosti unutar metode calculatePCorrection() računaju korekcije tlaka koje se primjenjuju na stare vrijednosti tlaka da bi se dobile nove. Nakon toga se provjerava konvergencija rezultata. Ako je konvergencija postignuta, petlja se prekida i u pozivajući program se vraća vrijednost koja označava uspješno završen korak. Ako do konvergencije nije došlo, cijeli se postupak nastavlja. Petlja će se izvršiti najviše maxIteracija puta. Ovaj je broj postavljen dovoljno velik da se može smatrati da ako rezultat nije dostignut u tolikom broju pokušaja da neće ni biti dostignut (rješenje je divergiralo), ali ipak dovoljno nizak da program ne upadne u dugotrajnu besmislenu blokadu. Ako nakon maxIteracija konvergencija nije dostignuta, petlja se prekida i u pozivajući program se vraća odgovarajuća vrijednost.

 

Proračun vrijednosti brzina za novi vremenski korak

Računanje novih brzina, kako je vidljivo u metodi advanceTimeStep(), vrši metoda calculateNewVelocities(). Kako ova metoda ima vrlo jednostavan kod koji samo za svaki element mreže poziva metodu calculateOneElementNewVelocity(), bitno je obratiti pažnju na ovu drugu metodu. Njen pseudokod se može prikazati otprilike kako slijedi:


     calculateOneElementNewVelocity (i, j)
          postavi vrijednosti karakterističnih susjednih veličina
          za svaki susjedni element koji je prepreka
               prilagodi karakteristične susjedne veličine
          izračunaj nove brzine prema diskretnom izrazu momentne jednadžbe
     kraj metode


Korištene oznake potrebnih čvorova


Pri tome su karakteristične susjedne veličine sve one vrijednosti tlaka i brzina koje su potrebne za rješavanje momentne jednadžbe. Unutar ove metode te veličine imaju imena dana prema stranama svijeta kako je prikazano na slici. Ovakav način zapisa je razumljiviji od korištenja indeksa polja, pogotovo uzme li se u obzir kompleksnost momentne jednadžbe u diskretnom obliku.

Proračun korekcija tlaka

Sljedeća metoda koja se poziva u advanceTimeStep() je  metoda calculatePCorrection(). Njen pseudokod se može prikazati kako slijedi:


    bool calculatePCorrection()
        za svaki element mreže
            postavi vrijednost korekcije tlaka na nula
            postavi vrijednost stare korekcije tlaka na nula
        ponavljaj do konvergencije ili najviše do maxIteracija puta
            postavi najveću korekciju tlaka na nula
            postavi najveću razliku korekcija tlaka na nula
            za svaki element mreže
                izračunaj korekciju tlaka
                ako je razlika nove i stare korekcije tekućeg elementa veća
                od dosad najveće razlike korekcije tlaka
                    postavi najveću razliku korekcije tlaka na razliku nove
                    i stare korekcije tekućeg elementa
                ako je korekcija tlaka tekućeg elementa veća od dosad
                najveće korekcije tlaka
                    postavi najveću korekciju tlaka na korekciju tlaka
                    tekućeg elementa
            ako je najveća razlika korekcije tlaka manja od uvjeta
            konvergencije
                korekcije tlaka su dostigle konačnu vrijednost; izađi iz
                metode
            inače
                za svaki element mreže
                    postavi staru korekciju na vrijednost nove korekcije
    kraj metode

 

Ova je metoda posebno bitna zbog iterativnog postupka koji dosad nije objašnjen. Radi se o jednostavnom postupku. Nove vrijednosti korekcija tlaka se izračunavaju sve dok najveća razlika korekcije između dvije uzastopne iteracije ne padne na prihvatljivu razinu. Unutar cijelog postupka, koji ne ovisi o ovome koraku, vrlo je bitno da se pamti najveća korekcija tlaka na mreži u apsolutnom iznosu. Ta je veličina, naime, mjerilo konvergencije algoritma SIMPLE.


Ova metoda za svaki element mreže poziva zasebnu metodu koja zapravo rješava Poissonovu jednadžbu. Njen je naziv calculateOneElementNewPressure(), a pseudokod se može prikazati na sljedeći način:


    calculateOneElementNewPressure(i, j)
        postavi vrijednosti karakterističnih susjednih veličina
        za svaki susjedni element koji je prepreka
            prilagodi karakteristične susjedne veličine
        izračunaj nove korekcije prema diskretnom izrazu Poissonove jednadžbe
    kraj metode


Karakteristične susjedne veličine se označavaju jednako kao kod rješavanja momentne jednadžbe, s tim da ovdje postoje dvije dodatne varijable za tlak: westPressure i southPressure.

 

Ostale metode

U klasi Solver postoje još neke dodatne pomoćne metode. Tako metoda switchVelocities() prije ulaska u glavnu petlju algoritma SIMPLE zapisuje tekuće vrijednosti brzina u polje starih brzina. Da bi se postupak ubrzao, umjesto prepisivanja svih vrijednosti jednostavno se zamijene samo imena polja, tj. zamijene se reference na ove objekte. Metoda applyPCorrection() vrši jednostavno zbrajanje tekućih vrijednosti tlaka i njihovih korekcija kako je predviđeno u četvrtom koraku algoritma SIMPLE. Slično, ali s brzinama, radi i applyVelocityCorrections(). Također, postoje metode za postavljanje različitih veličina na njihove početne vrijednosti.