SummationByParts/shallow_water/misc/fluxes.py

103 lines
2.5 KiB
Python
Executable File

#! /usr/bin/env python3
import sympy as sp
from sympy.utilities.codegen import codegen
x, y, t = sp.symbols("x,y,t")
rho, g = sp.symbols("rho,g", positive=True, real=True)
# Ignoring rho, assumed to be constant
eta = sp.Symbol("eta", positive=True, real=True)
etau, etav = sp.symbols("etau,etav", real=True)
u = etau / eta
v = etav / eta
q = sp.Matrix([eta, etau, etav])
E = sp.Matrix([eta * u, eta * u ** 2 + g * eta ** 2 / 2, eta * u * v])
F = sp.Matrix([eta * v, eta * u * v, eta * v ** 2 + g * eta ** 2 / 2])
q = sp.Matrix([eta, etau, etav])
A = E.jacobian(q)
sp.pprint(A)
B = F.jacobian(q)
sp.pprint(B)
f = sp.symbols("f")
coriolis = sp.Matrix([0, -f * v * eta, +f * u * eta])
sp.pprint(coriolis)
b = sp.symbols("b")
frictional = sp.Matrix([0, b * u * eta, b * v * eta])
sp.pprint(frictional)
print("A:")
# We can also diagonalise the transpose,
# which still gives the same (linearised) system.
# This results in a much nicer formulation for A+ and A-
A = A.T
S, D = A.diagonalize()
print("Diagonals:")
sp.pprint(D[0, 0])
sp.pprint(D[1, 1])
sp.pprint(D[2, 2])
print("S:")
sp.pprint(S)
print("SI:")
sp.pprint(sp.simplify(S.inv()))
m = abs(etau / eta) + abs(sp.sqrt(eta ** (3)) * sp.sqrt(g) / eta)
L = D + sp.Matrix([[m, 0, 0], [0, m, 0], [0, 0, m]])
Aplus = sp.simplify(S * L * S.inv()) / 2
Aplus = Aplus.T
L = D - sp.Matrix([[m, 0, 0], [0, m, 0], [0, 0, m]])
Aminus = sp.simplify(S * L * S.inv()) / 2
Aminus = Aminus.T
print("A plus:")
sp.pprint(Aplus)
print("A minus:")
sp.pprint(Aminus)
print("A S:")
sp.pprint(sp.simplify(Aminus - Aplus))
assert sp.simplify(S * D * S.inv() - A) == sp.Matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0]])
print("B:")
S, D = B.diagonalize()
print("Diagonals:")
sp.pprint(D[0, 0])
sp.pprint(D[1, 1])
sp.pprint(D[2, 2])
print("S:")
sp.pprint(S)
print("SI:")
sp.pprint(sp.simplify(S.inv()))
assert sp.simplify(S * D * S.inv() - B) == sp.Matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0]])
m = abs(etav / eta) + abs(sp.sqrt(eta ** (3)) * sp.sqrt(g) / eta)
L = D + sp.Matrix([[m, 0, 0], [0, m, 0], [0, 0, m]])
Bplus = sp.simplify(S * L * S.inv()) / 2
L = D - sp.Matrix([[m, 0, 0], [0, m, 0], [0, 0, m]])
Bminus = sp.simplify(S * L * S.inv()) / 2
print("B plus:")
sp.pprint(Bplus)
print("B minus:")
sp.pprint(Bminus)
print("B S:")
sp.pprint(sp.simplify(Bminus - Bplus))
assert sp.simplify((Bplus + Bminus) - B) == sp.Matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0]])
breakpoint()
code = codegen(
[("Aplus", Aplus), ("Aminus", Aminus), ("Bplus", Bplus), ("Bminus", Bminus)], "rust"
)
with open("autogen.rs", "w") as f:
f.write(code[0][1])