Start
Web-Artikel
Lexikon
Vorträge
Ausbildung
Essays
Rhetorik
Links
Autor
Kontakt
|
Astrophysik auf dem Computer
pdf
Das Computerlabor
Computer sind - wie mittlerweile in vielen anderen Berufszweigen auch - Werkzeuge eines Wissenschaftlers.
Dies ist zunächst unabhängig davon, ob seine Arbeit eher theoretischer oder eher experimenteller
Natur ist. Der Ausdruck Computing meint in den theoretischen bzw. numerischen Naturwissenschaften
alles, was die Lösung eines naturwissenschaftlichen Problems auf Computern umfasst.
In der theoretischen Physik ist der Computer zum virtuellen Labor geworden, das das physische Labor
der Experimentatoren in idealer Weise ergänzt. In vielen Fällen ist es möglich, das reale
Experiment bzw. den Vorgang in der Natur komplett auf dem Computer darzustellen. Dieses Verfahren nennt
man Simulation. Dazu werden Ablaufpläne einer numerischen Prozedur, Codes, in verschiedenen
Computersprachen entwickelt. Typisch im Bereich der numerischen Physik ist die Computersprache FORTRAN, deren
Bezeichnung sich von FORmula TRANslation ableitet und die in den letzten Versionen F77, F90, F95,
F2003 erschienen ist. Eine wachsende Bedeutung in der Physik erlangen die Computersprachen C und deren
objektorientierte Erweiterung C++. Das Symbol ++ ist übrigens in vielen Computersprachen der so
genannte Inkrementoperator. Damit ist C++ als etwas zu interpretieren, was C folgt (rhetorisch betrachtet
ist diese Benennung eine Analogie). Einen breiten Einsatzbereich hat nach
wie vor FORTRAN, was einerseits historisch bedingt ist: wenn alte Codes in FORTRAN verfügbar sind, wird
dieser in derselben Sprache erweitert; andererseits hat die Verwendung von FORTRAN nach wie vor technische
Vorteile, weil die FORTRAN-Compiler noch schneller sind als C-Compiler. Compiler sind Übersetzungsprogramme,
die die Programmiersprache ('Hochsprache') in Maschinensprache umsetzen - man sagt kompilieren. Die
Maschinensprache wiederum wird direkt vom Computerprozessor ausgeführt.
Entwickler in den Naturwissenschaften benutzen für die Lösung ihres physikalischen Problems in der
Regel eine Programmiersprache ihrer Wahl. Es ist allerdings auch möglich, Code-Fragmente in unterschiedlichen
Computersprachen miteinander zu koppeln und zwischen den Modulen mit Interfaces zu vermitteln.
Visualisierung
Jede Computersimulation ist im Prinzip zweigeteilt: zunächst wird das Problem mit numerischen Verfahren
gelöst. Bei dieser Berechnung fallen große Datenmengen an, die gebündelt und gespeichert werden
müssen, z.B. in Form einer ASCII- oder binären Datei, die Datenkolonnen enthält. Natürlich
kann man diese Rohdaten nicht unmittelbar physikalisch interpretieren. Daher schließt sich ein zweiter
Schritt an: die Visualisierung, also die Darstellung der Rohdaten mithilfe bildgebender Verfahren. Man
kann durchaus sagen, dass die Visualisierung ein eigenständiger Bereich neben Numerik und Coding
ist. Es ist nicht immer einfach zu entscheiden, wie man visualisieren muss (d.h. welche darzustellende
Größe, welche Diagrammform, welche
Dimensionalität etc.), um den wissenschaftlichen Gehalt adäquat darzustellen. Es gibt sogar im Allgemeinen
mehrere Wege ein und denselben Sachverhalt zu visualisieren. Und manchmal ist eine wissenschaftliche Entdeckung erst
mit einer geeignet gewählten Darstellungsform möglich! Insofern ist Visualisierung eine Kunst. Der
Betrachter einer wissenschaftlichen Graphik mag durchaus ihren künstlerischen Wert im einen oder anderen
Fall entdecken. Ein Beispiel für Visualisierung mit Mathematica zeigt die Graphik oben rechts, die
die Krümmungseigenschaften der Raumzeit eines rotierenden Schwarzen Loches illustriert: links, in einiger
Entfernung, ist die Raumzeit flach; rechts wird sie unendlich und markiert die Singularität (physikalische
Details unter Kretschmann-Skalar).
Die zunehmende Komplexität von Simulationen hat die beiden Schritte Datenberechnung und Visualisierung
voneinander entkoppelt. Der Theoretiker nutzt oft kommerzielle Visualisierungswerkzeuge, die relativ einfach
die Rohdaten einlesen und schnell darstellen. Zu diesen zählen typischerweise in der Physik und Astrophysik:
- Gnuplot, um zweidimensionale Diagramme oder Oberflächen in 3D darzustellen. Dabei ist die
Darstellung analytischer (auch vom Benutzer definierter) Funktionen sowie von zwei-, drei- oder mehrdimensionalen
Rohdaten sehr schnell möglich. Darstellungen mit Isokonturlinien oder -flächen, Projektionen sowie
zahlreiche andere Features werden unterstützt. Um mit Gnuplot arbeiten zu können, muss man sich als
Anwender Befehle und die Syntax dieser Software aneignen. Diese werden in einer Befehlszeile eingegeben. Mit
ein wenig Übung und Hilfestellungen aus dem Internet wird man schnell mit
Gnuplot vertraut und weiß es zu schätzen. Ein Vorteil ist, dass eine immer gleich gestaltete
Visualisierung mit einer Ladefunktion schnell aufgerufen werden kann, wenn alle nötigen Befehle einmal
als separate Textdatei (Script) gespeichert wurden. Viele wissenschaftliche Veröffentlichungen
enthalten Graphiken, die mit Gnuplot erzeugt werden.
- OpenDX (Open Data Explorer) und IDL (Interactive Data Language) bieten ähnliche
Funktionalitäten und darüber hinaus die Möglichkeit die Verteilung von skalaren oder vektoriellen
Größen im Simulationsgebiet farbenprächtig darzustellen. Zwei- und dreidimensionale, farbskalierte
Diagramme oder Isokonturliniendiagramme sind eine typische Anwendung dieser Werkzeuge. Animationen mit variablen
Parametern sind auch online möglich. Außerdem kann man Kamerafahrten durch gerechnete Daten generieren,
um sich einen dreidimensionalen Eindruck von der Lösung zu verschaffen (Rendering). OpenDX
unterscheidet sich von IDL darin, dass die Funktionalitäten in suggestiven Elementen (black boxes)
zusammengefasst werden und die Erzeugung eines Bilds oder einer Animation aus den Rohdaten einer Datenpipeline
folgen. Eine graphische Benutzeroberfläche (graphical user interface, GUI) dient der Organisation dieser
Elemente bestimmter Funktion. Diese visuelle Datenpipeline wird automatisch von OpenDX in Visualisierungscode
übersetzt, der ausgeführt wird. IDL ist eher formelorientiert. Die Visualisierungsschritte werden
als Befehlszeilen mit eigener Syntax aufgerufen. Auch hier gilt, dass Prozeduren systematisiert und gespeichert werden
können.
- Mathematica ist ein kommerzielles Werkzeug, um vielfältige mathematische Operationen durchzuführen:
Ob eine Gleichung analytisch oder numerisch gelöst werden soll, Bestimmung von Nullstellen eines Polynoms, Wurzelziehen,
bis zur Vektor-, Matrizen- und Tensorrechnung (mit geeigneter Zusatzsoftware) ist diese Software einen zuverlässiger
Begleiter in der Mathematik und den Naturwissenschaften. Natürlich können Gleichungen und Simulationsdaten
in 2D und 3D visualisiert werden. Ähnlich wie bei der anderen Software muss sich der Anwender mit der Syntax
vertraut machen und kann Visualisierungsabläufe speichern.
- Daneben existieren weitere kommerzielle Visualisierungswerkzeuge mit ähnlicher Konzeption und Funktionalität.
Natürlich wird der Visualisierungsteil auch oft eigenhändig programmiert. Dabei sollte man allerdings auf
bestehende Programmbibliotheken zurückgreifen - das Rad muss nicht neu erfunden werden. Bewährte Bibliotheken
(Libraries, kurz Libs) sind beispielsweise vtk (visualization tool kit) und OpenGL.
Hardware
Computing betrifft auch den Aspekt der Hardware. Zur Simulation benötigt man neben der Software
(dem Code) einen Computer auf dem der Code ausgeführt wird (Code Run). Zwei wesentliche Eigenschaften
sind für den Anwender im Allgemeinen und dem simulierenden Physiker im Speziellen von Interesse: die Taktrate
des Prozessors, die die Zeit bestimmt, die nötig ist, bis der Code ausgeführt wurde und der
Arbeitsspeicher (memory) des Computers, der festlegt, wie viele Datenmengen zeitweilig
zwischengespeichert werden können, weil sie immer wieder während des Code Runs benötigt werden.
Die Festplatte (hard disk) ist insofern wichtig, weil die Rohdaten, Bilder oder Animationen auf irgendeinem
Medium langfristig gespeichert werden müssen. Dazu sind viele Giga- und Terabyte Speicher nötig, weil der
Code mehrmals mit verschiedenen Parametern aufgerufen wird (Parameterstudien). Für einfache Probleme der
Physik genügt ein herkömmlicher PC. Häufig sind die Fragestellungen der theoretischen Physik so
komplex, dass das numerische Gebiet einerseits hochaufgelöst werden muss und andererseits die Ausführung des
Codes in einer vertretbaren Zeit erfolgen soll. Dies erfordert Hochleistungsrechner, die man auch
Supercomputer nennt. Im Unterschied zu herkömmlichen PCs füllen diese Rechenmaschinen ganze Zimmer
oder Hallen und bestehen aus vielen Einzelprozessoren, salopp gesprochen vielen einzelnen PCs. In Deutschland
verfügen zahlreiche wissenschaftliche Institute über Supercomputer, die auch für industrielle Anwendungen
genutzt werden. Typische Hochleistungsrechner für wissenschaftliche Anwendungen sind vom Typ Cray,
Origin, NEC-SX oder Earthsimulator. Die Architektur dieser Rechner basiert in der Regel auf
multiprocessoring: mehrere, parallele Prozessoren können angesprochen und verwaltet werden, um Kalkulationen
sehr effizient und vor allem schnell durchzuführen. Dazu verwendet man in Verbindung mit einer Programmiersprache
(C, C++, FORTRAN) weitere Befehle in Codes, die speziell die parallele Verwaltung der Prozessoren betreffen. Diese
heißen beispielsweise MPI (Message-Passing Interface) oder OpenMP, die Methode selbst nennt man
Parallele Programmierung (Parallel Coding).
Objekt-Orientierung
Moderne Bestrebungen in der Programmierung und auch in der theoretischen Astrophysik kann man in eine Philosophie
einordnen, die sich Objekt-Orientierung (OO) nennt. In der Astrophysik mag man das Akronym OOCA bemühen,
das für Object-Oriented Computing in Astrophysics steht. Objekt-Orientierung ist eine Zielsetzung, eine
moderne Philosophie bei Programmiersprachen, also bei der Software; man kann aber auch von OO im Bereich der Hardware
sprechen. Objekt-Orientierung ist eine konzeptionelle Strategie, die eng an Ordnungsschemata des menschlichen Gehirns
angelehnt ist. Im Alltag denken und handeln wir objektorientiert: Begrifflichkeiten werden nach
Zusammengehörigkeitkriterien gekapselt und Funktionen spezifischen Objekten zugeordnet. Gerade das macht den
Denkprozess und Handlungsabläufe äußerst effizient und schnell.
Objekt-Orientierung auf der Software-Seite heißt, diese Strategie konsequent auf Programmiersprachen
zu übertragen. Dies löste vor einigen Jahren die klassische prozedurale Technik - zumindest in
einigen Bereichen - ab, und es vollzog sich dadurch ein konzeptioneller Wechsel, bei dem nun die Funktionalität
und Wiederverwendbarkeit (Recycling) des Codes, aber nicht mehr länger die Daten im Vordergrund standen.
Objekt-Orientierung ist auch eine ergonomische Realisierung des Programmierens, weil sich die Computersprache der
Denkweise des Menschen anpasst und nicht umgekehrt.
Mittlerweile gibt es eine ganze Reihe von Sprachen, wie C++ oder Java, die sich einer Objekt-Orientierung bedienen.
C++ ist die abwärtskompatible Weiterentwicklung der rein prozeduralen Sprache C. Hier heißen die
gekapselten Objekte Klassen. Die Abwärtskompatibilität zu C hat Einschränkungen zur Folge,
die einer ästhetischen Objekt-Orientierung zuwiderlaufen. Rigider ist da schon Java. Im Internet kennt
man die Java Applets, kleine Applikationen ('Miniprogramme'), die in Java geschrieben sind. Java hat sich im
Web durchgesetzt, weil es vor allem plattformunabhängig ist. Java kann jedoch als voll funktionelle Computersprache
mehr, weist aber auch viele Unterschiede zu C++ auf (keine Templates, keine Überladung von Funktionen etc.). Java,
federführend entwickelt von SUN Microsystems, darf nicht mit dem JavaScript verwechselt werden, das die Firma
Netscape für den gleichnamigen Internetbrowser entwickelt hat.
Java ist allerdings weniger flexibel und daher auf dem wissenschaftlichen Sektor weniger gebräuchlich. Sehr
gebräuchlich, speziell in der Physik am Computer, ist nach wie vor FORTRAN. Diese Programmiersprache wird aus
Gründen der Zweckmäßigkeit (Verwendung älterer Softwaremodule; noch bessere Compiler) immer noch
verwendet, ist jedoch im Grunde keine moderne Programmiersprache, auch wenn sie mittlerweile aufgesetzte, objektorientierte
Features bietet. Es zeigt sich jedoch, dass die Entscheidung, welche Sprache man nun verwendet nicht nur von
Zweckmäßigkeit geprägt ist, sondern vor allem vom Industriezweig und auch vom persönlichen Geschmack
des Entwicklers - dessen 'Philosophie' - abhängt.
Objekt-Orientierung auf der Hardware-Seite heißt, Hardwarekomponenten nach einzelnen Abschnitten in der Abfolge
des numerischen Algorithmus ('Jobs') zu kapseln. Unter dem Stichwort Parallelisieren läuft eine bekannte
Methode, die von vielen Entwicklern und theoretischen Astrophysikern praktiziert wird. Hierbei wird der Quellcode so
erstellt, dass die Rechenauslastung auf verschiedene Prozessoreinheiten (CPUs) verteilt werden kann. Dies setzt man
speziellen Befehlen um, die die Kommunikation zwischen den Prozessoren regeln und direkt in den Code eingefügt
werden. Sehr gebräuchlich ist in diesem Zusammenhang MPI, ein Message-Passing Interface Standard.
Es ist auch möglich den vollen Arbeitsspeicher zu segmentieren und zur Laufzeit den einzelnen CPUs Memory
zuzuordnen. Eine weitere Möglichkeit ist es die Codes Cache-effizient zu programmieren. Hierbei werden
kleine Einheiten des Arbeitsspeichers mit äußerst kurzen Zugriffszeiten genutzt, um den Code sehr schnell
zu machen.
Arbeitsalltag in der Theoretischen Physik
Das Arbeitsfeld eines Theoretikers umfasst heutzutage folgende Gebiete:
- Mit der Analytik verschafft man sich einen globalen Überblick über die zu lösenden
Gleichungen der Physik. Früher lösten die Naturwissenschaftler in Ermangelung von Computern
Problemstellungen - wenn möglich - komplett analytisch, d.h. leiteten eine exakte Lösung der
Gleichungen ab. Im Prinzip genügten dafür Bleistift und Papier. Dies ist heute - aufgrund der
Komplexität der Probleme - eher die Ausnahme. Das analytische Terrain ist klein geworden. Theoretiker
müssen sich heute der Numerik und Computertechnologie bedienen. Analytik ist
und bleibt jedoch der erste Schritt in der Annäherung an das physikalische Problem, beispielsweise um die
Form der Grundgleichungen abzuleiten oder sie weiter zu modifizieren. An einem bestimmten Punkt setzen dann
Numerik und Informatik ein.
- Die Numerik ist im Prinzip angewandte Mathematik und stellt Verfahren zur Verfügung, um
analytisch nicht mehr lösbare Gleichungen näherungsweise - man sagt numerisch - zu
lösen. So sind die Differentiale und Integrale der Infinitesimalrechnung analytisch für einen
beliebig kleinen Grenzwert definiert. Eine numerische Berechnung erfordert bei vorhandenen Differentialoperatoren
('Ableitungen') eine Diskretisierung. Hier muss man die infinitesimalen Werte im Grenzwertübergang
endlich wählen. Andererseits muss hinter dem Komma an einer bestimmten Stelle abgebrochen werden. In der
Informatik gibt es zu diesem Zweck Zahlenformate mit unterschiedlichen Genauigkeiten, z.B. float,
double, long etc., die entsprechend 4, 8 und 10 Byte Speicher belegen und eine Angabe von
6, 10 und 10 Stellen nach dem Komma erlauben.
Aus diesem Grund ist die Approximation zwingend und 'naturgegeben' in der Simulation auf Computern. Daraus
resultiert die so genannte numerische Auflösung, also eine oder mehrere Kenngrößen, die
bestimmen, wie genau der Zahlenwert der Lösung einer Gleichung ist oder wie scharf ein simuliertes Bild
ist.
Als simples Beispiel sei die numerische Integration erwähnt, wo man unter anderem Newton-,
Runge-Kutta-Verfahren oder Gauß-Quadraturen verwendet, um Funktionen oder Gleichungen zu
integrieren. Die Integrale werden dabei in endliche Summen zerlegt und bis auf eine gewisse Genauigkeit
approximiert.
Aufgabe der Numerik ist es nun, leistungsstarke und stabile Algorithmen für eine schnelle, effiziente
Berechnung eines mathematischen Problems bereitzustellen, die möglichst genau an die exakte (bzw.
physikalische) Lösung herankommen. Dieses Streben der numerischen Lösung an die tatsächliche
bezeichnet man mit Konvergenz. Genau dies sind Kriterien die an einen Programmiercode zu stellen
sind: Stabilität und Konvergenz. Um diese qualitativen Maßstäbe gewährleisten
zu können, sind ausgiebige Tests des Codes nötig. Es erweist sich als sinnvoll,
Standardprobleme mit dem Code zu simulieren. Am besten eignet sich ein analytisches Standardproblem, dessen
Lösung exakt bekannt. Ein Vergleich der bekannten mit der simulierten Lösung hilft, die
Leistungsfähigkeit und Richtigkeit eines Codes zu überprüfen. Die Tests zeigen dann den
Gültigkeits- bzw. Operationsbereich (z.B. Domäne physikalischer Parameter) des Codes und seine Güte
an. Diese Testphase läuft unter dem Stichwort Code-Validierung und beansprucht typischerweise viel
Zeit des Entwicklers oder Entwicklungsteams.
- Der letzte Schritt lässt sich prägnant mit angewandter Informatik umreißen. Eine
wesentliche und zeitintensive Beschäftigung eines Theoretikers ist es, den Code sehr effizient und schnell
zu machen, weil sich die komplexen Simulationen im Allgemeinen am Rande der aktuellen Leistungsfähigkeit
der Hardware bewegen.
Es ist daher klar, dass wissenschaftliche Berechnungen in der Regel auf Hochleistungsrechenanlagen (high
performance computers) laufen. Nach Tagen bis Wochen liegen dann Ergebnisse der komplizierten Rechnungen
in Form von unvisualisierten Rohdaten vor. Die besten Hochleistungsrechenanlagen besitzen heutzutage einige
hunderttausend CPUs (Computer Processing Units, also Prozessoren), die eine maximale Leistung (Peak
Performance) von einigen hundert Tflops aufbieten, also hunderte Billionen Fließkommazahlen-Berechnungen
(floating point operations) pro Sekunde! International werden die Supercomputer mit dem LINPACK-Benchmark
verglichen und bilden die weltweite Top500 der Hochleistungsrechner. Der schnellste Computer der Welt
ist derzeit BlueGene/L (IBM), der im amerikanischen Energieministerium am
Lawrence Livermore National Laboratory in den USA steht. Hier
leisten 131072 CPUs eine Performance von 280.6 Tflops! (Stand März 2006).
Supercomputer sind daher wichtige Werkzeuge der täglichen, theoretischen Arbeit. Die intensiven Tests der
Codes kosten sehr viel Zeit, sind aber absolut unerlässlich, um eine Richtigkeit der Ergebnisse
gewährleisten und die Grenzen der Leistungsfähigkeit des Codes beurteilen zu können.
Der letzte Arbeitschritt beim Computing ist die Visualisierung. Die Rohdaten, in der Regel einige tausend
Zahlenkolonnen, müssen durch bildgebende Verfahren in eine handliche, verständliche Form gebracht werden.
Schließlich werden die als Diagramme dargestellten Daten und die simulierten Bilder sowie Animationen ('Movies')
physikalisch interpretiert. So münden Simulationen in ein Verständnis der Natur.
Hinweis: Die Seite Astrophysiker - Ausbildung und Beruf stellt die Arbeit eines
Astronomen/Astrophysikers vor.
Computing in der Astrophysik
Die theoretische Astrophysik bietet sehr viele Themenfelder, in denen der Computer benutzt wird. Es ist heutzutage
schon fast die Regel astrophysikalische Probleme mit Computern zu simulieren. Typische Aufgabenfelder sind in der
Terminologie der Physik:
- Strahlungsphysik und Strahlungstransport,
- Kern-, Atom-, Molekül- und Plasmaphysik,
- Hydrodynamik und Magnetohydrodynamik,
- Newtonsche Gravitationsphysik und Relativitätstheorie,
- Thermodynamik,
- klassische Gase und Quantengase,
- Feldtheorie,
- Streutheorie
- und deren Überlappungsgebiete.
Eine typische Fragestellung ist, dass das zu untersuchende Phänomen mit einer oder einem Satz von
gekoppelten Differentialgleichungen beschrieben werden kann. Ein Beispiel für ein solches
Gleichungssystem steht rechts (die Grundgleichungen der allgemein relativistischen, idealen
Magnetohydrodynamik, GRMHD). Diese Gleichungen werden dann diskretisiert und mit numerischen Verfahren
(Finite Differenzen Methoden, Finite Elemente Methoden, Finite Volumen Methoden etc.) gelöst. In
mannigfaltiger Weise können die Gleichungen in Produkte aus Lösungsvektor und Matrizen
(im Prinzip nichts anderes als Zahlenkolonnen angeordnet in Zeilen und Spalten) umformuliert werden, so dass
die Lösung des Ausgangsproblems mit der Matrizenrechnung bewältigt werden kann. Das
Ergebnis wird schließlich visualisiert, interpretiert und mit experimentellen Daten verglichen.
Dieser Vergleich offenbart Stärken und Unzulänglichkeiten des meist vereinfachenden
physikalischen Modells. Im besten Fall resultieren ein erkenntnistheoretischer Gewinn, ein physikalisches
Verständnis der Abläufe in der Natur und eine Richtungsweisung für zukünftige
physikalische Modelle.
Ich habe während meiner Ausbildung in der Theoriegruppe von Max Camenzind an der
Landessternwarte Heidelberg die Vorteile der
Objekt-Orientierung von C++ genutzt. Im Rahmen meiner Diplomarbeit Emissionslinienprofile
akkretierender Scheiben um rotierende Schwarze Löcher haben wir einen relativistischen
Ray Tracer für Strahlenausbreitung in der Kerr-Metrik
entwickelt. Dieser Kerr Black Hole Ray Tracer (KBHRT) berechnet wie Licht, das in der
Nähe eines Schwarzen Lochs ausgestrahlt wird, sich durch die gekrümmte Raumzeit bis
zum astronomischen Beobachter in großer Entfernung bewegt. Mittels dieser Software sind
relativistische Spektren berechenbar, die man sonst nur durch astronomische Beobachtungen
erhält. Ein Vergleich dieser Simulationen mit der tatsächlichen Beobachtung liefert
Hinweise auf ein mögliches Schwarzes Loch im Kosmos und Aufschlüsse über dessen
Eigenschaften.
Die Graphische Benutzeroberfläche (GUI) des Tracers basiert auf den Microsoft Foundation
Classes (MFC) der Windows-Welt. Damit hat die Software die vertraute Gestalt der Windows-Fenster.
Die wesentlichen Teile, wie der Renderer und die anderen Berechnungsroutinen sind jedoch
plattformunabhängig konzipiert und können ohne viel Aufwand in die LINUX-Welt auf der
Basis von QT-Klassen übertragen werden.
Ich habe den Ray Tracer seither kontinuierlich weiterentwickelt und an astrophysikalische
Fragestellungen angepasst. Weitere Einzelheiten zu diesem Thema bieten die Artikel
Gefangenes Licht - Relativistisches Ray Tracing sowie
Röntgenlinien - Sendboten von Loch und Scheibe.
pdf
nach oben
© Andreas Müller, August 2007
|
|