Übersicht

Hintergrund

Bevor ich wusste, was eine partielle Differentialgleichung ist, habe ich mal versucht, eine Fluidsimulation zu programmieren. Das resultierende Fluid war höchst kompressibel, da in Ermangelung entsprechender Kenntnisse keine Poissongleichung zur Anwendung kam.

Etliche Jahre später habe ich mir das kleine alte Programm nochmal vorgenommen und etwas umfangreicheres daraus gemacht. In dem Programm konnte man nun unter verschiedenen vordefinierten Setups auswählen. Die interessanteste Erweiterung war, das das Fluid über Potentialfelder mit sich selbst wechselwirken konnte. Damit ließen sich Dinge wie Sternhaufen und Kristallgitter realisieren.

Nochmals ein paar Jahre später habe ich das Programm von Java nach C++ portiert und inkompressible Fluide und Videoerzeugung hinzugefügt, außerdem Modi, die mit Fluiden wenig zu tun hatten, wie zum Beispiel SmoothLife, Reaktions-Diffusions-Advektions-Systeme und Animationen auf Basis von Perlin-Rauschen.

Den C++-Quellcode für das Programm kannst du hier herunterladen. Das Programm benutzt Qt und läuft in den meisten Modi flüssig auf meinem 4-Kern-8-Hyperthread-2,2GHz-64bit Prozessor.

Bedienung

Man kann das Fluid mit der Maus und Modifizierer-Tasten beeinflussen. Die genaue Bedeutung der Maustasten kann modusabhängig variieren, aber bei den meisten Fluid-Modi gilt folgende Belegung:

Linke Maustaste:
Fluid hinzufügen
Rechte Maustaste:
Fluid bewegen
Strg+Linke Maustaste:
Fluid entfernen
Strg+Rechte Maustaste:
Eine einzelne Fluid-Zelle auf hohe Geschwindigkeit bringen
Shift+Linke Maustaste:
Lichtquelle bewegen (Nur bei Visualisierung mit Bumpmapping-Shader)

Die Schaltfläche Clear setzt bei den meisten Modi alles auf Null, bei manchen hält man damit aber nur die Bewegung an.

Ausgewählte Programm-Modi

Im Folgenden stelle ich einige der vordefinierten Modi des Programms vor. Einige der Beispielvideos habe ich nicht von YouTube aus eingebettet, weil die Qualität sonst zu schlecht wäre.

Tinte

Tintenkleckse

Dieser Modus entspricht bis auf die Farbgebung und Bildgröße dem ursprünglichen Programm.

Beispielvideo:


(mp4, webm, YouTube)

Tintenstrudel

Hier habe ich zwei Gravitationszentren eingebaut, die das Fluid strudeln lassen. Außerdem wird das Fluid noch in Bewegungsrichtung beschleunigt, so dass es nach einer Weile schnell genug ist um den Strudel zu verlassen.

Beispielvideo:


(mp4, webm, YouTube)

Sterne

Sterne / 1

Wenn das Fluid über ein regularisiertes Coulomb-Potential mit sich selbst wechselwirkt, bildet es Ballungen, die dem newtonschen Gravitationsgesetz folgen und sich wie Sterne gegenseitig anziehen.

Beispielvideo:


(mp4, webm, YouTube)

Sterne / grobkörnig

Das funktioniert sogar dann noch einigermaßen, wenn ich gewisse Simulationsparameter auf extreme Werte stelle. Jetzt explodieren die Sterne manchmal.

Beispielvideo:


(mp4, webm, YouTube)

Sterne / feinkörnig

So ähnlich wie das Vorige, aber mit mehr und kleineren Sternen.

Beispielvideo:


(mp4, webm, YouTube)

Sterne / instabil

Hier sind die Sterne winzig klein und explodieren manchmal zu Gas. Die entstehende Druckwelle hinterlässt einen Leerraum, was zu interessanten Mustern führt.

Beispielvideo:


(mp4, webm, YouTube)

Sterne / instabil / bump

Das gleiche nochmal mit einem Shader mit Bumpmapping. Die Leerräume von den Explosionen sehen jetzt aus wie kleine Krater.

Beispielvideo:


(mp4, webm, YouTube)

Sterne / viele

Hier ist das Ergebnis einer großen Simulation mit vielen winzigen Sternen. Die Simulation selbst lief allerdings nicht ganz so flüssig.


(mp4, webm, YouTube)

Kristalle

Kristall / kollaps / klein

Ein Coulomb-Potential zieht das Fluid ins Zentrum einer Zusammenballung. Wenn man dagegen ein Potential verwendet, das das Fluid in ein ringförmiges Gebiet um das Zentrum herum zieht, bekommt man hexagonale Kristallgitter. Diese Kristalle können unter ihrer eigenen Gravitation in sich zusammenbrechen. Übrig bleibt ein degenerierter Klumpen. Wenn sich zwei solche Klumpen begegnen, werden einer oder beide zu Gaswolken zerfetzt, aus denen sich wieder neue Kristalle bilden.

Beispielvideo:


(mp4, webm, YouTube)

Kristall / kollaps / langsam

Hier das ganze so ähnlich nochmal in größer.


(mp4, webm, YouTube)

Gaskristallisation / quasi2

Wenn man ein Potential verwendet, das mehrere ringförmige Minima mit den richtigen Radien hat, können andere Kristallstrukturen entstehen. Hier sind welche mit fünfeckigen Gitterfehlern. Außerdem kann man das Gesamtpotential (grün) und die Stärke des Kraftfeldes sehen (blau).

Beispielvideo:


(mp4, webm, YouTube)

starburst

In diesem Modus gibt es verschieden Arten von Objekten: Gas, kleine Sonnen, Kristalle, scheinbar starr rotierende unregelmäßige Klumpen und pulsierende Mega-Sonnen, in denen die Klumpen eingeschmolzen werden.

Beispielvideo:


(mp4, webm, YouTube)

starburst / klein

Dieser Modus hat oberflächliche Ähnlichkeit mit starburst, aber keine Klumpen oder Mega-Sonnen.

Beispielvideo:


(mp4, webm, YouTube)

Waber

waber / waberlohe

Hier habe ich mal mehrere abstoßende statt anziehende Ringpotentiale benutzt.

Beispielvideo:


(mp4, webm, YouTube)

waber / wabenlohe

Wenn man zusätzlich noch einen kleinen anziehenden Ring dazunimmt, bekommt man Kristallstrukturen, sobald die Dichte des Fluids hoch genug ist. Nimmt die Dichte wieder ab, lösen sich die Kristalle auf.

Beispielvideo:


(mp4, webm, YouTube)

waber / schmelze

Wenn man zwei anziehende Ringpotentiale mit dem goldenen Schnitt als Radienverhältnis nimmt, sind nicht nur hexagonale Kristalle möglich, sondern auch pentagonale Quasikristalle. In diesem Modus sind die hexagonalen Kristalle bei hohen Dichten stabil, während die Quasikristalle bei niedrigeren Dichten vorherrschend sind. Wenn die Dichte abnimmt, wandelt sich die hexagonale Phase unmerklich in die quasikristalline um.

Beispielvideo:


(mp4, webm, YouTube)

waber / floaters / gliders

Bei diesem komplexen Selbstwechselwirkungs-Kraftfeld mit abstoßenden und anziehenden Komponenten entsteht eine Vielzahl von stabilen Formen, die sich gegenseitig anrempeln. Manche sind auf solche Weise asymmetrisch, dass sie in einer bestimmten Richtung beschleunigen.

Beispielvideo:


(mp4, webm, YouTube)

waber / übersättigt / vielePhasen

In diesem Modus hat das Fluid eine interessante Struktur, und es gibt viele kristalline Phasen. Manche davon sind sehr selten und schwer zu beobachten. Eine interessante Sache, die man machen kann: Solange Fluid hinzufügen, bis es kristallisiert. Dann zwei horizontale Strömungen in entgegengesetzter Richtung erzeugen. Der Kristall verflüssigt sich durch die Bewegung wieder, aber nach einer Weile werden die mittleren Gebiete der beiden Strömungen wieder kristallin und hart, weil die Strömung dort fast keine Scherung hat. Etwas später entsteht eine Instabilität: die beiden kristallinen Balken verbiegen sich und verflüssigen sich schließlich ganz. Die Strömung nimmt dann die Form zweier entgegengesetzt rotierender Wirbel an.

In dem Video kann man ab der Sekunde 1:34 auch das Verhalten von Quasikristall-Korngrenzen beobachten.


(mp4, webm, YouTube)

waber / übersättigt / vielePhasen / bump

Dies ist der soeben beschriebene Modus, aber mit Bumpmap-Visualisierung. Die kristallinen Phasen sehen damit nicht so doll aus, aber dafür die Flüssigkeit.

Beispielvideo:


(mp4, webm, YouTube)

Inkompressibel

Feuerspur

... oder ist es Kaffee mit Milch? Ich trinke aber keinen Kaffee. Also ist es Feuer.

In diesem Modus ist das Fluid nur fast inkompressibel, es gibt eine coulombartige Selbstanziehung heller Gebiete. Darum breiten sich dunkle Gebiete aus, während helle sich zusammenziehen. Der Advektionsschritt erhält nicht die Menge der hellen Substanz. Wenn man mit der Maus eine helle Spur malt, zieht sie sich zusammen und verwirbelt dabei auf interessante Weise.

Beispielvideo:


(mp4, webm, YouTube)

waber / inkompressibel

Dieser Modus ist fast genauso definiert wie waber / übersättigt / vielePhasen, aber mit inkompressibler, substanzerhaltender Advektion. Die Simulation läuft in der Größe 1024×1024 sehr langsam, darum lieber das Video anschauen:


(mp4, webm, YouTube)

Reaktions-Diffusions-Advektions-Systeme

Diese Modi implementieren verschiedene Reaktionsdiffusionsgleichungen, gekoppelt mit inkompressibler Advektion.

rda / Gray-Scott

Dieser Modus implementiert das Gray-Scott-Modell mit Parameterwerten, die zu sich vermehrenden Punkten führen (k = 0,0570 und f = 0,0220).

Beispielvideo:


(mp4, webm, YouTube)

rda / f3

Ein besserer Name ist mir dafür nicht eingefallen. Diese Reaktionsdiffusionsgleichung verträgt sich nicht gut mit Advektion: Wenn man das Fluid bewegt, wird alles dunkel. Nachdem man die Bewegung angehalten hat, erholt es sich wieder. Dabei werden die Stromlinien der Bewegung sichtbar.

Beispielvideo:


(mp4, webm, YouTube)

rda / Lorenz / schnell

Dieser RDA-Gleichung habe ich den offiziellen Namen Das Streben nach Harmonie trägt in sich den Keim des Zerwürfnisses gegeben. Warum? Es gibt blaue und orange Bereiche, die ständig ihre Form verändern. Wenn sich irgendwo ein zu großer homogener Bereich bildet, wechselt ein Teil davon spontan die Farbe.

Beispielvideo:


(mp4, webm, YouTube)

Technische Details: Der Reaktions-Anteil der Gleichung ist an jedem Punkt die Differentialgleichung für den Lorenz-Attraktor. Dieser besteht aus zwei Schleifen (im Programm repräsentiert durch die beiden Farben). Der Zustandsvektor eines Systems, das von dieser Differentialgleichung regiert wird, bewegt sich auf einer der beiden Schleifen im Kreis und wechselt ab und zu auf chaotische Weise die Schleife, wenn er an eine kritische Stelle kommt. Durch den Diffusionssteil der RD-Gleichung ist jedes zu einem Punkt gehörige System mit den Nachbarpunkten gekoppelt. Wenn ein System an die kritische Stelle kommt, seine Nachbarsysteme aber an einer nicht-kritischen Stelle derselben Schleife sind, wird es durch den Einfluss der Nachbarsysteme auf der Schleife gehalten. Sind dagegen die Systeme in einer Region ausreichend phasenähnlich, so kommen sie gemeinsam an die kritische Stelle und wechseln möglicherweise alle zusammen auf die andere Schleife.

Prozedural

Manche Modi haben nichts mit Fluiden zu tun, sind auch nicht interaktiv, sondern berechnen Bildsequenzen auf prozedurale Weise. Die Farbe jedes Pixels in einer angezeigten Bildsequenz kann unabhängig von den anderen Pixeln aus seinen Raum-Zeit-Koordinaten berechnet werden, indem eine aus verschiedenen Funktionen zusammengesetzte Funktion ausgewertet wird. Besonders wichtig dabei ist die Perlin-Rauschfunktion, mit der sich unregelmäßige Muster erzeugen lassen.

Perlin / schwarzes Loch

Unter Blitzen und Schockwellen wird ein schwarzes Loch immer größer.

Video:


(mp4, webm, YouTube)

SmoothLife

SmoothLife ist eine Verallgemeinerung von Conways Game of Life von diskreten Gittern auf auf kontinuierliche Funktionen. Wie sich die Lebendigkeit eines Punktes im Laufe der Zeit ändert, hängt von der Gesamtlebendigkeit in einer scheibenförmigen und einer darumherumliegenden ringförmigen Nachbarschaft ab.

Man kann die Simulationsdaten mit dem Mausrad vergrößern und verkleinern. Dabei werden die Größen der Nachbarschaften angepasst, so dass die Muster sich nachher noch so ähnlich verhalten wie vorher.

SmoothLife / pap / bump

Dieser Modus implementiert SmoothLife, so, wie es in diesem Paper beschrieben ist, aber mit einem Bumpmap-Shader für die Anzeige.

Video:


(mp4, webm, YouTube)

SmoothLife / yt / bump

Dieser Modus implementiert SmoothLife, so, wie es in diesem YouTube-Video vorgemacht wurde. Die Formel für die Übergangsfunktion hat einen subtilen Unterschied zu der aus dem Paper. Außerdem ist die Zeitentwicklung theoretisch kontinuierlich (praktisch läuft es dann doch wieder auf diskrete Zeitschritte mit Euler-Integration hinaus).

Video:


(mp4, webm, YouTube)

SmoothLife / pap / wabbel

Diese SmoothLife-Übergangsfunktion produziert komisch wabbelnde Gleiter.

Video:


(mp4, webm, YouTube)

Wellengleichung mit Faserpotential

Diese Modi werden auf einer eigenen Seite beschrieben: Wellengleichung mit Faserpotential.

Teilen:  E-Mail Twitter Facebook LinkedIn Reddit
Impressum und Kontakt | © 2016-07-31 injamben.de

Diskussion

Bisher keine Beiträge

Kommentar abgeben


:
-- Gib den voranstehenden Text ein: