12.5. Hyperbolische partielle Differentialgleichung#
In der Struktur Dynamik und auch anderen Anwendungen trifft man oft auf Systeme von der semidiskreten Form
wobei \(M\) die Massenmatrix, \(C\) eine viskose Dämpfung, \(K\) die Steifigkeitsmatrix und \(F\) ein Vektor gegeben durch die angewandten Kräfte ist. Wir nehmen an, dass \(M, C, K\) symmetrisch sind. Die Massenmatrix \(M\) sei positiv definit und \(C, K\) positiv-semidefinit. Für die vollständige Beschreibung des Anfangswertproblems (12.10) benötigen wir Anfangswerte für
12.5.1. Newmark Verfahren#
Die wohl am meisten benutzten Verfahren gehöhren in die Familie der Newmark Verfahren:
wobei \(d_n, v_n, a_n\) Approximationen von \(d(t_n), \dot{d}(t_n), \ddot{d}(t_n)\) sind. Die Parameter \(\beta\) und \(\gamma\) bestimmen die Stabilitäts- und Genauigkeits-Charakteristik.
Es gibt verschiedene Formen für die Implementierung. Oft wird die sogenannte \(a\)-Form benutzt, welche auf der Beschleunigung \(a\) aufbaut. Analoges mit der Deformation \(d\) führt zu äquivalenten Implementationen. Wir betrachten hier die a-Form und definieren folgende Predictors:
und für \(d_{n+1}\) und \(v_{n+1}\) aus (12.11) folgend die Correctors:
Die initiale Beschleunigung \(a_0\) kann aus
berechnet werden. Die noch unbekannte Beschleunigung zum neuen Zeitschritt \(a_{n+1}\) ist nun gegeben durch die Lösung des Gleichungssystems
Mit den Gleichungen (12.13) folgt \(d_{n+1}\) und \(v_{n+1}\), die Schätzwerte \(\tilde{d}_{n+1}, \tilde{v}_{n+1}\) werden korrigiert. Entsprechend nennt man die Gleichungen (12.13) Correctors.
Für \(\beta = \frac{1}{4}\) und \(\gamma = \frac{1}{2}\) wird quasi die mittlere Beschleunigung benutzt. Wir erhalten in dem Fall die Trapezmethode, welche bedingungslos stabil ist.
12.5.2. Anwendung#
Wir betrachten als Anwendung die Wellengleichung
Show code cell content
from netgen.geom2d import unit_square
from ngsolve import *
from ngsolve.webgui import Draw
import numpy as np
import matplotlib.pyplot as plt
from netgen.geom2d import CSG2d, Circle
circle = Circle((0,0),2,bc='wall')
geo = CSG2d()
geo.Add(circle)
#mesh = Mesh(unit_square.GenerateMesh(maxh=0.05))
mesh = Mesh(geo.GenerateMesh(maxh=0.3))# etwas grob 0.15
V = H1(mesh,order = 4, dirichlet='wall')#'bottom|right|top|left')
u = V.TrialFunction()
v = V.TestFunction()
gfu = GridFunction(V)
gfv = GridFunction(V)# 1. Zeitableitung
gfa = GridFunction(V)# 2. Zeitableitung
V.ndof
2305
K = BilinearForm(V)
K += 0.1*grad(u)*grad(v)*dx
K.Assemble()
M = BilinearForm(V)
M += u*v*dx
M.Assemble();
Als Quelle benutzen wir einen Puls von der Zeitlänge \(\Delta t\) mit einer beschränkten örtlichen Ausdehnung:
x0=0
y0=0
f = 5000*exp(-((x-x0)**2+(y-y0)**2)/0.01)
F = LinearForm(V)
F += f*v*dx
F.Assemble();
Draw(f,mesh,'f')
BaseWebGuiScene
Sei \(M^* = M + \beta\, \Delta t^2\, K\). Wir wählen die Trapezmethode:
beta = 1/4
gamma = 1/2
dt = 1/125.0
mstar = K.mat.CreateMatrix()
mstar.AsVector().data = M.mat.AsVector() + beta*dt**2 * K.mat.AsVector()
Wir berechnen nun die zeitabhängige Lösung.
scene = Draw(gfu,mesh,'u', min=-2,max=2,autoscale=False)
freq=1/(10*dt)*2
t = 0
gfu.vec[:] = 0
gfv.vec[:] = 0
gfa.vec[:] = 0
T = 10
# predictors
utilde = gfu.vec.CreateVector()
vtilde = gfu.vec.CreateVector()
b = gfu.vec.CreateVector()
mip = mesh(0,0)
ui = [gfu(mip)]
ti = [t]
with TaskManager():
while t < T:
#F.Assemble() # muss bei zeitabhängiger Linearform aufgerufen werden.
# predictors berechnne
utilde.data = gfu.vec + dt * gfv.vec + dt**2/2*(1-2*beta)*gfa.vec
vtilde.data = gfv.vec + (1-gamma)*dt*gfa.vec
# a neu berechnen
if t < 1/(2*freq): # ein Impuls
b.data = F.vec
b.data *= np.sin(2*np.pi*freq*t)**2
b.data -= K.mat*utilde
else:
b.data = - K.mat*utilde
gfa.vec.data = mstar.Inverse(freedofs=V.FreeDofs(),inverse='sparsecholesky')*b
# corrector berechnen
gfu.vec.data = utilde + beta*dt**2*gfa.vec
gfv.vec.data = vtilde + gamma*dt*gfa.vec
# Redraw
scene.Redraw()
ui.append(gfu(mip))
ti.append(t)
t+=dt