Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HybridizationPC #152

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
018d586
hybridization_pc
JHopeCollins Nov 21, 2023
4654197
Merge branch 'master' into hybridization_pc
JHopeCollins Dec 1, 2023
3ad47da
serial linear swe with hybridization
JHopeCollins Dec 4, 2023
86a262d
serial galewsky with hybridization
JHopeCollins Dec 5, 2023
fa33d62
serial straka with hybridization
JHopeCollins Dec 5, 2023
537c6c8
pass appctx through SerialMiniapp
JHopeCollins Dec 7, 2023
7d80111
auxiliarypc for hybridisation
JHopeCollins Dec 7, 2023
e2d7f2e
use lswe form for hybridisation pc
JHopeCollins Dec 7, 2023
b93bed0
fully linear swe pc for hybridisation
JHopeCollins Dec 7, 2023
4692156
galewsky hybridisation gamg testing
JHopeCollins Dec 11, 2023
f55cf34
Merge branch 'auxiliary_block_pc' into hybridization_pc
JHopeCollins Dec 11, 2023
a58fdbd
add function_mean calculation to utils
JHopeCollins Dec 11, 2023
d26ecf0
move AuxiliaryPC for serial problem to utils.serial submodule
JHopeCollins Dec 11, 2023
112916c
Precondition SWE blocks with LSWE AuxiliaryOperatorPC
JHopeCollins Dec 11, 2023
e0fcea8
Merge branch 'master' into hybridization_pc
JHopeCollins Dec 13, 2023
96adbc7
script to run galewsky serially and write out Checkpoints at given in…
JHopeCollins Dec 14, 2023
353b4e1
script to read in a checkpoint file and write out to vtk
JHopeCollins Dec 14, 2023
dbb43ec
gamg parameters for hybridised linear swe
JHopeCollins Dec 20, 2023
ccab72c
lswe preconditioning for swe galewsky test
JHopeCollins Dec 21, 2023
1caf787
write b and f to swe checkpoints
JHopeCollins Jan 5, 2024
00ad91e
max block iterations for galewsky
JHopeCollins Jan 5, 2024
34747b9
Merge branch 'cpx_z_constants' into hybridization_pc
JHopeCollins Jan 5, 2024
14a55ce
script to load up a shallow water checkpoint and set up a complex_pro…
JHopeCollins Jan 5, 2024
aab428b
construct mg mesh for swe complex_proxy sandbox
JHopeCollins Jan 8, 2024
99fba56
Merge branch 'hybridization_pc' of https://github.com/firedrakeprojec…
JHopeCollins Jan 8, 2024
2bcc119
test swe cpx pc for all eigenvalues with random rhs
JHopeCollins Jan 16, 2024
936c993
scripts for the real and complex lswe blocks
JHopeCollins Jan 23, 2024
d3f20e5
correct broken element for hybridised block pc
JHopeCollins Jan 24, 2024
ef40fcb
Merge branch 'master' into hybridization_pc
JHopeCollins Jan 24, 2024
3fc7d46
swe complex block script for schur complement hybridisation pc
JHopeCollins Jan 25, 2024
6578113
move swe block and serial scripts to seperate directories
JHopeCollins Jan 25, 2024
b57ba7a
hybr_schur with serial and pdg scripts
JHopeCollins Jan 26, 2024
b35a130
homebrew HybridizationPC using SCPC
JHopeCollins Feb 25, 2024
ac09983
mover BrokenHDivProjector to utils
JHopeCollins Feb 26, 2024
93093c9
hybridised scpc with complex_proxy block
JHopeCollins Feb 26, 2024
fb5f017
add function space checking to BrokenHDivProjector
JHopeCollins Feb 26, 2024
fa62c63
only apply HDiv constraint to trace space component-wise
JHopeCollins Feb 26, 2024
c5e8fe0
hdiv broken projections via real space or directly on complex space?
JHopeCollins Feb 28, 2024
b372070
Fixed hybridisation for the complex LSWE block using SCPC
JHopeCollins Feb 28, 2024
e03864b
gamg with HybridisationSCPC for lswe
JHopeCollins Feb 29, 2024
5ed71a9
remove print statement from HDivBrokenProjections
JHopeCollins Mar 1, 2024
2d8eddd
HybridisedSCPC in linear_gravity_bumps script
JHopeCollins Mar 1, 2024
7ddfb10
force reusing lu factorisation of hybridised swe
JHopeCollins Mar 13, 2024
01b6baf
force reusing lu factorisation of serial hybridised swe
JHopeCollins Mar 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 222 additions & 0 deletions case_studies/shallow_water/blockpc/lswe_cpx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
import firedrake as fd
from firedrake.petsc import PETSc
from asQ.complex_proxy import vector as cpx

import utils.shallow_water.gravity_bumps as lcase
from utils import shallow_water as swe
from utils.planets import earth
from utils import units

import numpy as np
from scipy.fft import fft, fftfreq

PETSc.Sys.popErrorHandler()
Print = PETSc.Sys.Print


# get command arguments
import argparse
parser = argparse.ArgumentParser(
description='Test preconditioners for the complex linear shallow water equations.',
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)

parser.add_argument('--dt', type=float, default=1.0, help='Timestep in hours (used to calculate the circulant eigenvalues).')
parser.add_argument('--nt', type=int, default=16, help='Number of timesteps (used to calculate the circulant eigenvalues).')
parser.add_argument('--theta', type=float, default=0.5, help='Parameter for implicit theta method. 0.5 for trapezium rule, 1 for backwards Euler (used to calculate the circulant eigenvalues).')
parser.add_argument('--alpha', type=float, default=1e-3, help='Circulant parameter (used to calculate the circulant eigenvalues).')
parser.add_argument('--eigenvalue', type=int, default=0, help='Index of the circulant eigenvalues to use for the complex coefficients.')
parser.add_argument('--seed', type=int, default=12345, help='Seed for the random right hand side.')
parser.add_argument('--ref_level', type=int, default=3, help='Icosahedral sphere mesh refinement level with mesh hierarchy. 0 for no mesh hierarchy.')
parser.add_argument('--show_args', action='store_true', help='Output all the arguments.')

args = parser.parse_known_args()
args = args[0]

if args.show_args:
Print(args)

# eigenvalues
nt, theta, alpha = args.nt, args.theta, args.alpha
dt = args.dt*units.hour

gamma = args.alpha**(np.arange(nt)/nt)
C1 = np.zeros(nt)
C2 = np.zeros(nt)

C1[:2] = [1/dt, -1/dt]
C2[:2] = [theta, 1-theta]

D1 = np.sqrt(nt)*fft(gamma*C1)
D2 = np.sqrt(nt)*fft(gamma*C2)
freqs = fftfreq(nt, dt)

d1 = D1[args.eigenvalue]
d2 = D2[args.eigenvalue]

d1 = 1 + 1j
d2 = 1

d1c = cpx.ComplexConstant(d1)
d2c = cpx.ComplexConstant(d2)

dhat = (d1/d2) / (1/(theta*dt))

mesh = swe.create_mg_globe_mesh(ref_level=args.ref_level,
coords_degree=1)
x = fd.SpatialCoordinate(mesh)

# case parameters
g = earth.Gravity
f = lcase.coriolis_expression(*x)
H = lcase.H


# generate linear solver
def make_solver(W, form_mass, form_function,
d1c, d2c, L, sparams, form_trace=None):

# block forms
M = cpx.BilinearForm(W, d1c, form_mass)
K = cpx.BilinearForm(W, d2c, form_function)

A = M + K

if form_trace is not None:
Tr = cpx.BilinearForm(W, 1, form_trace)
A += Tr

wout = fd.Function(W).assign(0)
problem = fd.LinearVariationalProblem(A, L, wout)
solver = fd.LinearVariationalSolver(problem,
solver_parameters=sparams)
return wout, solver


# shallow water equation forms
def form_mass(u, h, v, q):
return swe.linear.form_mass(mesh, u, h, v, q)


def form_function(u, h, v, q, t=None):
return swe.linear.form_function(mesh, g, H, f,
u, h, v, q, t)


# shallow water equation forms with trace variable
def form_mass_tr(u, h, tr, v, q, s):
return form_mass(u, h, v, q)


def form_function_tr(u, h, tr, v, q, dtr, t=None):
K = form_function(u, h, v, q, t)
n = fd.FacetNormal(mesh)
K += (
g*fd.jump(v, n)*tr('+')
)*fd.dS
return K


def form_trace(u, h, tr, v, q, dtr, t=None):
n = fd.FacetNormal(mesh)
Khybr = (
+ fd.jump(u, n)*dtr('+')
)*fd.dS
return Khybr


V = swe.default_function_space(mesh)
W = cpx.FunctionSpace(V)

Vu, Vh = V.subfunctions
Vub = fd.FunctionSpace(mesh, fd.BrokenElement(Vu.ufl_element()))
Tr = fd.FunctionSpace(mesh, "HDivT", Vu.ufl_element().degree())
Vtr = Vub*Vh*Tr

Wtr = cpx.FunctionSpace(Vtr)

# random rhs
L = fd.Cofunction(W.dual())
Ltr = fd.Cofunction(Wtr.dual())

# PETSc solver parameters
lu_params = {
'ksp_type': 'preonly',
'pc_type': 'lu',
'pc_factor_mat_solver_type': 'mumps'
}

rtol = 1e-5
sparams = {
'ksp': {
'monitor': None,
'converged_reason': None,
'rtol': rtol,
# 'view': None
},
}
sparams.update(lu_params)

scpc_params = {
'mat_type': 'matfree',
'ksp_type': 'preonly',
'pc_type': 'python',
'pc_python_type': 'firedrake.SCPC',
'pc_sc_eliminate_fields': '0, 1',
'condensed_field': lu_params,
}

sparams_tr = {
'ksp': {
'monitor': None,
'converged_reason': None,
'rtol': rtol,
# 'view': None
},
}
# sparams_tr.update(scpc_params)
sparams_tr.update(lu_params)

# trace component should have zero rhs
np.random.seed(args.seed)
L.assign(0)
Ltr.assign(0)
for dat in L.dat:
dat.data[:] = np.random.rand(*(dat.data.shape))
# L.subfunctions[1].assign(0)

# break velocity
from utils.broken_projections import BrokenHDivProjector
projector = BrokenHDivProjector(Vu)
projector.project(L.subfunctions[0].sub(0), Ltr.subfunctions[0].sub(0))
projector.project(L.subfunctions[0].sub(1), Ltr.subfunctions[0].sub(1))

# break height
Ltr.subfunctions[1].assign(L.subfunctions[1])

w, solver = make_solver(W, form_mass, form_function,
d1c, d2c, L, sparams)
wtr, solver_tr = make_solver(Wtr, form_mass_tr, form_function_tr,
d1c, d2c, Ltr, sparams_tr, form_trace)

PETSc.Sys.Print("")
PETSc.Sys.Print("Solving original system")
solver.solve()
PETSc.Sys.Print("")
PETSc.Sys.Print("Solving system with trace")
solver_tr.solve()

u, h = w.subfunctions
utr, htr, tr = wtr.subfunctions

umend = fd.Function(W.subfunctions[0])
projector.project(utr.sub(0), umend.sub(0))
projector.project(utr.sub(1), umend.sub(1))

umerr = fd.errornorm(u, umend)/fd.norm(u)
uerr = fd.errornorm(u, utr)/fd.norm(u)
herr = fd.errornorm(h, htr)/fd.norm(h)
PETSc.Sys.Print("")
PETSc.Sys.Print(f"Velocity errornorm = {uerr}")
PETSc.Sys.Print(f"Depth errornorm = {herr}")
PETSc.Sys.Print(f"Mended velocity errornorm = {umerr}")
Loading