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

Enable slate tensors with variable-layers extruded mesh #1884

Merged
merged 1 commit into from
Nov 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 0 additions & 6 deletions firedrake/slate/slac/kernel_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ def __init__(self, expression, tsfc_parameters=None):
"""
assert isinstance(expression, slate.TensorBase)

if expression.ufl_domain().variable_layers:
raise NotImplementedError("Variable layers not yet handled in Slate.")

# Collect terminals, expressions, and reference counts
temps = OrderedDict()
coeff_vecs = OrderedDict()
Expand Down Expand Up @@ -429,9 +426,6 @@ def __init__(self, expression, tsfc_parameters=None):

assert isinstance(expression, slate.TensorBase)

if expression.ufl_domain().variable_layers:
raise NotImplementedError("Variable layers not yet handled in Slate.")

self.expression = expression
self.tsfc_parameters = tsfc_parameters
self.bag = None
Expand Down
46 changes: 46 additions & 0 deletions tests/slate/test_scalar_tensors_extr.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import numpy as np
from math import ceil

from firedrake import *

Expand All @@ -7,3 +8,48 @@ def test_constant_one_tensor():
mesh = ExtrudedMesh(UnitIntervalMesh(5), 5)
one = Constant(1, domain=mesh)
assert np.allclose(assemble(Tensor(one * dx)), 1.0)


def test_mass_matrix_variable_layers_extrusion():
# construct variable layer mesh with height increasing from H1 to H2
L = 50
H1 = 2.
H2 = 42.
dx_ = 5.0
nx = round(L/dx_)
dy_ = 2.0
tiny_dy = 0.01

# create mesh
mesh1d = IntervalMesh(nx, L)
layers = []
cell = 0
xr = 0
for i in range(nx):
xr += dx_ # x of rhs of column (assumed to be the higher one)
height = H1 + xr/L * (H2-H1)
ncells = ceil(height/dy_)
layers.append([0, ncells])
cell += ncells

mesh = ExtrudedMesh(mesh1d, layers, layer_height=dy_)
# move top nodes to create continuous, piecewise linear top boundary
# with height increasing from H1 to H2
x = mesh.coordinates.dat.data_ro[:, 0]
y = mesh.coordinates.dat.data_ro[:, 1]
# left top nodes is moved up from H1 to H1+tiny_dy, to avoid zero edge on boundary
height = np.maximum(H1 + x/L * (H2-H1), H1+tiny_dy)
mesh.coordinates.dat.data[:, 1] = np.minimum(height, y)
V = FunctionSpace(mesh, "DG", 1)
v = TestFunction(V)
u = TrialFunction(V)

A1 = assemble(Tensor(v*u*dx)).M.values
A2 = assemble(v*u*dx).M.values
A3 = assemble(Tensor(v*u*dx).inv).M.values

# check A1==A2
assert np.allclose(A1, A2, rtol=1e-12)

# check A2*A3==Identity
assert np.allclose(np.matmul(A2, A3), np.eye(*A2.shape), rtol=1e-12)