Skip to content
Snippets Groups Projects
Commit d2c80ca8 authored by Andreas Klöckner's avatar Andreas Klöckner
Browse files

Make weak-form operators work

parent c34f4454
No related branches found
No related tags found
No related merge requests found
...@@ -343,10 +343,6 @@ class ExecutionMapper(mappers.Evaluator, ...@@ -343,10 +343,6 @@ class ExecutionMapper(mappers.Evaluator,
def exec_diff_batch_assign(self, insn): def exec_diff_batch_assign(self, insn):
field = self.rec(insn.field) field = self.rec(insn.field)
repr_op = insn.operators[0] repr_op = insn.operators[0]
if not isinstance(repr_op, sym.RefDiffOperator):
# FIXME
raise NotImplementedError()
# FIXME: There's no real reason why differentiation is special, # FIXME: There's no real reason why differentiation is special,
# execution-wise. # execution-wise.
# This should be unified with map_elementwise_linear, which should # This should be unified with map_elementwise_linear, which should
...@@ -376,21 +372,24 @@ class ExecutionMapper(mappers.Evaluator, ...@@ -376,21 +372,24 @@ class ExecutionMapper(mappers.Evaluator,
noperators = len(insn.operators) noperators = len(insn.operators)
result = discr.empty( result = discr.empty(
dtype=field.dtype, extra_dims=(noperators,)).with_queue(self.queue) queue=self.queue,
dtype=field.dtype, extra_dims=(noperators,),
allocator=self.bound_op.allocator)
for grp in discr.groups: for grp in discr.groups:
if grp.nelements == 0: if grp.nelements == 0:
continue continue
# FIXME: Should make matrices on device and cache them matrices = repr_op.matrices(grp)
diff_matrices = grp.diff_matrices()
diff_matrices_ary = np.empty(( # FIXME: Should transfer matrices to device and cache them
matrices_ary = np.empty((
noperators, grp.nunit_nodes, grp.nunit_nodes)) noperators, grp.nunit_nodes, grp.nunit_nodes))
for i, op in enumerate(insn.operators): for i, op in enumerate(insn.operators):
diff_matrices_ary[i] = diff_matrices[op.rst_axis] matrices_ary[i] = matrices[op.rst_axis]
knl()(self.queue, knl()(self.queue,
diff_mat=diff_matrices_ary, diff_mat=matrices_ary,
result=grp.view(result), vec=grp.view(field)) result=grp.view(result), vec=grp.view(field))
return [(name, result[i]) for i, name in enumerate(insn.names)], [] return [(name, result[i]) for i, name in enumerate(insn.names)], []
......
...@@ -88,41 +88,43 @@ class StrongAdvectionOperator(AdvectionOperatorBase): ...@@ -88,41 +88,43 @@ class StrongAdvectionOperator(AdvectionOperatorBase):
self.flux(pair)) self.flux(pair))
return ( return (
-self.v.dot(sym.nabla(self.ambient_dim)*u) - self.v.dot(sym.nabla(self.ambient_dim)*u)
+ sym.InverseMassOperator()( + sym.InverseMassOperator()(
sym.FaceMassOperator()( sym.FaceMassOperator()(
flux(sym.int_tpair(u)) flux(sym.int_tpair(u))
+ flux(sym.bv_tpair(sym.BTAG_ALL, u, self.inflow_u))))) + flux(sym.bv_tpair(sym.BTAG_ALL, u, self.inflow_u))
# FIXME: Add back support for inflow/outflow tags
#+ flux(sym.bv_tpair(self.inflow_tag, u, bc_in))
#+ flux(sym.bv_tpair(self.outflow_tag, u, bc_out))
)))
class WeakAdvectionOperator(AdvectionOperatorBase): class WeakAdvectionOperator(AdvectionOperatorBase):
def flux(self): def flux(self, u):
return self.weak_flux() return self.weak_flux(u)
def sym_operator(self): def sym_operator(self):
from grudge.symbolic import ( u = sym.var("u")
Field,
BoundaryPair,
get_flux_operator,
make_stiffness_t,
InverseMassOperator,
RestrictToBoundary)
u = Field("u")
# boundary conditions ------------------------------------------------- # boundary conditions -------------------------------------------------
bc_in = Field("bc_in") bc_in = self.inflow_u
bc_out = RestrictToBoundary(self.outflow_tag)*u # bc_out = sym.interp("vol", self.outflow_tag)(u)
stiff_t = make_stiffness_t(self.dimensions) def flux(pair):
m_inv = InverseMassOperator() return sym.interp(pair.dd, "all_faces")(
self.flux(pair))
flux_op = get_flux_operator(self.flux()) return sym.InverseMassOperator()(
np.dot(
self.v, sym.stiffness_t(self.ambient_dim)*u)
- sym.FaceMassOperator()(
flux(sym.int_tpair(u))
+ flux(sym.bv_tpair(sym.BTAG_ALL, u, bc_in))
return m_inv(np.dot(self.v, stiff_t*u) - ( # FIXME: Add back support for inflow/outflow tags
flux_op(u) #+ flux(sym.bv_tpair(self.inflow_tag, u, bc_in))
+ flux_op(BoundaryPair(u, bc_in, self.inflow_tag)) #+ flux(sym.bv_tpair(self.outflow_tag, u, bc_out))
+ flux_op(BoundaryPair(u, bc_out, self.outflow_tag))
)) ))
# }}} # }}}
......
...@@ -214,10 +214,20 @@ class RefDiffOperatorBase(ElementwiseLinearOperator): ...@@ -214,10 +214,20 @@ class RefDiffOperatorBase(ElementwiseLinearOperator):
class RefDiffOperator(RefDiffOperatorBase): class RefDiffOperator(RefDiffOperatorBase):
mapper_method = intern("map_ref_diff") mapper_method = intern("map_ref_diff")
@staticmethod
def matrices(element_group):
return element_group.diff_matrices()
class RefStiffnessTOperator(RefDiffOperatorBase): class RefStiffnessTOperator(RefDiffOperatorBase):
mapper_method = intern("map_ref_stiffness_t") mapper_method = intern("map_ref_stiffness_t")
@staticmethod
def matrices(element_group):
assert element_group.is_orthogonal_basis()
mmat = element_group.mass_matrix()
return [dmat.T.dot(mmat.T) for dmat in element_group.diff_matrices()]
# }}} # }}}
# }}} # }}}
...@@ -349,10 +359,7 @@ class RefMassOperatorBase(ElementwiseLinearOperator): ...@@ -349,10 +359,7 @@ class RefMassOperatorBase(ElementwiseLinearOperator):
class RefMassOperator(RefMassOperatorBase): class RefMassOperator(RefMassOperatorBase):
@staticmethod @staticmethod
def matrix(element_group): def matrix(element_group):
import modepy as mp return element_group.mass_matrix()
return mp.mass_matrix(
element_group.basis(),
element_group.unit_nodes)
mapper_method = intern("map_ref_mass") mapper_method = intern("map_ref_mass")
......
...@@ -208,10 +208,11 @@ def test_2d_gauss_theorem(ctx_factory): ...@@ -208,10 +208,11 @@ def test_2d_gauss_theorem(ctx_factory):
("rect2", [4, 8]), ("rect2", [4, 8]),
("rect3", [4, 6]), ("rect3", [4, 6]),
]) ])
@pytest.mark.parametrize("op_type", ["strong", "weak"])
@pytest.mark.parametrize("flux_type", ["upwind"]) @pytest.mark.parametrize("flux_type", ["upwind"])
@pytest.mark.parametrize("order", [3, 4, 5]) @pytest.mark.parametrize("order", [3, 4, 5])
def test_convergence_advec(ctx_factory, mesh_name, mesh_pars, flux_type, order, def test_convergence_advec(ctx_factory, mesh_name, mesh_pars, op_type, flux_type,
visualize=False): order, visualize=False):
"""Test whether 2D advection actually converges""" """Test whether 2D advection actually converges"""
cl_ctx = cl.create_some_context() cl_ctx = cl.create_some_context()
...@@ -268,13 +269,20 @@ def test_convergence_advec(ctx_factory, mesh_name, mesh_pars, flux_type, order, ...@@ -268,13 +269,20 @@ def test_convergence_advec(ctx_factory, mesh_name, mesh_pars, flux_type, order,
-v.dot(x)/norm_v -v.dot(x)/norm_v
+ sym.var("t", sym.DD_SCALAR)*norm_v) + sym.var("t", sym.DD_SCALAR)*norm_v)
from grudge.models.advection import StrongAdvectionOperator from grudge.models.advection import (
StrongAdvectionOperator, WeakAdvectionOperator)
discr = Discretization(cl_ctx, mesh, order=order) discr = Discretization(cl_ctx, mesh, order=order)
op = StrongAdvectionOperator(v, op_class = {
"strong": StrongAdvectionOperator,
"weak": WeakAdvectionOperator,
}[op_type]
op = op_class(v,
inflow_u=u_analytic(sym.nodes(dim, sym.BTAG_ALL)), inflow_u=u_analytic(sym.nodes(dim, sym.BTAG_ALL)),
flux_type=flux_type) flux_type=flux_type)
bound_op = bind(discr, op.sym_operator()) bound_op = bind(discr, op.sym_operator())
#print(bound_op)
#1/0
u = bind(discr, u_analytic(sym.nodes(dim)))(queue, t=0) u = bind(discr, u_analytic(sym.nodes(dim)))(queue, t=0)
...@@ -309,7 +317,7 @@ def test_convergence_advec(ctx_factory, mesh_name, mesh_pars, flux_type, order, ...@@ -309,7 +317,7 @@ def test_convergence_advec(ctx_factory, mesh_name, mesh_pars, flux_type, order,
last_u = event.state_component last_u = event.state_component
if visualize: if visualize:
vis.write_vtk_file("fld-%04d.vtu" % step, vis.write_vtk_file("fld-%s-%04d.vtu" % (mesh_par, step),
[("u", event.state_component)]) [("u", event.state_component)])
error_l2 = bind(discr, error_l2 = bind(discr,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment