Praktikum zur Vorlesung Numerik partieller Differentialgleichungen I

Mario Ohlberger, Felix Schindler

Blatt 00, 16.10.2019

Aufgabe 0

(i) einmalige Einrichtung

Dazu müssen auf Ihrem Rechner die Befehle python3 und virtualenv verfügbar sein. Das können Sie überprüfen, indem Sie ein Terminal starten (unter Ubuntu: Super/Windows Taste, terminal eingeben, Return) und die folgenden Befehle eingeben:

python3 --version
virtualenv --version

Beide Befehle sollten Ihnen die jeweilige Version des Programms anzeigen (und keine Fehlermeldung). Zur Einrichtung gehen Sie folgendermaßen vor:

  • Ins HOME Verzeichnis wechseln und einen Projekt-Ordner anlegen
cd      # ins HOME Verzeichnis wechseln
pwd     # Ort des aktuellen Verzeichnises anzeigen
ls -lh  # Inhalt des aktuellen Verzeichnisses anzeigen
mkdir NPDGL1 # ein neues Verzeichnis erstellen
cd NPDGL1    # in dieses Verzeichnis wechseln
pwd
ls -lh
  • eine virtuelle Umgebung für die Programmierung mit Python schaffen
virtualenv --python=python3 python_umgebung_NPDGL1
ls -lh
  • die virtuelle Umgebung aktivieren
source python_umgebung_NPDGL1/bin/activate
  • benötigte Software in der virtuellen Umgebung installieren
pip install --upgrade pip
pip install pymor[full]
pip install notebook
du -sh python_umgebung_NPDGL1

Dabei installiert pip install pymor[full] das neueste Release von pyMOR (momentan 0.5.2). Mehr dazu finden Sie auf https://pymor.org (gehen Sie dort auf View on Github und wählen anstelle von branch: master links oben Tags: 0.5.2 aus, um die entsprechende README.md anzuzeigen).

  • Arbeitsverzeichnis erstellen
mkdir notebooks

(ii) ab jetzt jedes mal

  • ins Projektverzeichnis wechseln
cd ~/NPDGL1
  • die virtuelle Umgebung aktivieren
source python_umgebung_NPDGL1/bin/activate
  • Notebook server starten
jupyter-notebook --notebook-dir=notebooks

(iii) Blatt 00 nutzbar machen

  • Laden Sie sich von der Homepage der Vorlesung blatt_00.ipynb herunter und speichern Sie dieses im Verzeichnis NPDGL1/notebooks/ als blatt_00.ipynb.

  • Starten Sie den Notebook server (siehe ii) und führen Sie blatt_00.ipynb aus.

Ab jetzt können Sie direkt im jeweiligen Übungsblatt arbeiten, fügen Sie dazu einfach direkt nach der Aufgabenstellung mit + (oben links) eine neue Code Zelle hinzu. Eine Code Zelle können Sie mit STRG + Return ausführen. Hilfe zu einem Typ Foo oder einer Objekt foo können Sie mit Foo? oder foo? erhalten.

In [ ]:
# führen Sie in einem Notebook immer die folgenden Befehle als erstes aus

%matplotlib notebook
import numpy as np
from pymor.basic import *

Ab jetzt ist die numpy Bibliothek unter np verfügbar und alles aus pymor.basic direkt verfügbar.

Definition: vereinfachtes Diffusionsproblem

Wir betrachten ein vereinfachtes stationäres Diffusionsproblem. Sei dazu

  • ein beschränktes polygonales Gebiet $\Omega \subset \mathbb{R}^2$ mit Lipschitz-Rand $\partial \Omega$,
  • eine Diffusion $A: \Omega \to \mathbb{R}$ und
  • eine rechte Seite $f: \Omega \to \mathbb{R}$

gegeben. Gesucht ist die Lösung $u: \Omega \to \mathbb{R}$, sodass

$$\begin{align} -\nabla\cdot( A \nabla u ) &= f &&\text{in } \Omega\\ u &= 0 &&\text{auf } \partial \Omega, \end{align}$$

(im schwachen Sinne, siehe Kapitel 1) erfüllt ist.

Aufgabe 1: Gebiete und Gitter

  1. Suchen Sie in der pyMOR Dokumentation auf docs.pymor.org/ nach einer Klasse, die das Gebiet $$\Omega = [0, 1]^2$$ mit Dirichlet-Randwerten modellieren kann und legen Sie ein entsprechendes Objekt mit Namen omega an. Nutzen Sie dazu auch die Möglichkeit des jupyter Notebooks, sich zu einem beliebigen Objekt mit Hilfe des ?-postfix die Dokumentation anzeigen zu lassen (z.B. np.array?).
  1. Suchen Sie nach einer Möglichkeit ein konformes Dreiecksgitter $\mathcal{T}_h$ als Partitionierung des Gebiets $\Omega$ mit 16 Dreiecken zu erstellen, und geben Sie folgende Informationen aus:

    • Dimension d des Gitters
    • Anzahl der Elemente (Kodimension 0 Entitäten, in diesem Fall Dreiecke) im Gitter
    • Anzahl der Kanten (Kodimension 1 Entitäten, in diesem Fall Intervalle) im Gitter
    • Anzahl der Knoten (Kodimension d Entitäten, Punkte) im Gitter
    • die Position eines jeden Knoten des Gitters mit Hilfe einer for-Schleife

    Vergleichen Sie die Positionen der Knoten mit der Dokumentation.

Aufgabe 2: analytische Funktionen vektorisiert implementieren

Sei $f: \Omega \to \mathbb{R}$ gegeben durch $f(x_0, x_1) := x_0 \cdot x_1$.

  1. Schreiben Sie eine Funktion f, die die Auswertung von $f$ and einem Punkt $x$ modelliert und werten Sie die Funktion f für jeden Knotenpunkt des Gitters einzeln mit Hilfe einer for-Schleife aus.
  1. Erstellen Sie ein feineres Gitter mit $1024^2$ Intervallen und messen Sie die benötigte Zeit, um f an jedem Knotenpunkt des feineren Gitters auszuwerten.
  1. Versuchen Sie, f an allen Knotenpunkten des groben Gitters gleichzeitig auszuwerten. Warum funktioniert das nicht?
  1. Schreiben Sie eine vektorisierte Variante von f, welche die elementweisen Operationen des numpy.ndarray ausnutzt und werten Sie diese Variante für alle Knotenpunkte des feineren Gitters gleichzeitig aus und messen Sie die benötigte Zeit.
  1. Erstellen Sie eine ExpressionFunction, um $f$ zu modellieren, werten Sie diese an allen Knotenpunkten des feinen Gitters aus und messen Sie die benötigte Zeit.

Aufgabe 3: Diffusionsproblem in pyMOR modellieren

Modellieren Sie das vereinfachte Diffusionsproblem mit

  • $A = 1$
  • $f = 1$

mit Hilfe eines analytischen Problems in pyMOR.

  1. Suchen Sie nach einer geeigneten Klasse, um $A$ und $f$ als Funktionen in pyMOR zu modellieren.
  1. Machen Sie sich mit der Klasse StationaryProblem vertraut und legen Sie ein problem an, welches die gewünschten Datenfunktionen enthält.

Aufgabe 4: Diffusionsproblem in pyMOR diskretisieren

  1. Diskretisieren Sie das stationäre Problem mit einer CG Diskretisierung (CG = continuous Galerkin = stetige Finite Elemente, siehe Kapitel 2), indem Sie die entsprechende Funktion aus dem pymor.discretizers Paket verwenden.
    • Rufen Sie diese Funktion mit dem analytischen Problem auf.
    • Was ist der Rückgabewert?
  1. Berechnen Sie eine approximative Lösung u_h des vereinfachten Diffusionsproblems mit Hilfe der Diskretisierung. Machen Sie sich dazu mit der Dokumentation von StationaryDiscretization vertraut oder finden Sie die entsprechende Funktion interaktiv (um die Methoden eines Objektes foo anzuzeigen, schreiben Sie foo. und drücken Sie Tab).
  1. Visualisieren Sie die approximative Lösung mit Hilfe der Diskretisierung

Aufgabe 5: Approximationsgüte

Berechnen Sie Approximationen u_h für verschieden Gitterweiten h = 1/2, 1/4, 1/16, 1/64, indem Sie das diameter Argument der Funktion discretize_stationary_cg nutzen.

  • Berechnen und visualisieren Sie diese Approximationen und vergleichen Sie sie.
  • Unterdrücken Sie die automatische Ausgabe des Diskretizers mit Hilfe von set_log_levels({'pymor': 'WARN'})
  • Geben Sie den jeweiligen diskreten Lösungsraum aus.