diff --git a/grudge/execution.py b/grudge/execution.py index 2fa47b91fa271f558eb78d350114ab5aac46bf5e..ca6b7dd99c7108fd1a5a39b3770dde4d6c940e87 100644 --- a/grudge/execution.py +++ b/grudge/execution.py @@ -343,10 +343,6 @@ class ExecutionMapper(mappers.Evaluator, def exec_diff_batch_assign(self, insn): field = self.rec(insn.field) 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, # execution-wise. # This should be unified with map_elementwise_linear, which should @@ -376,21 +372,24 @@ class ExecutionMapper(mappers.Evaluator, noperators = len(insn.operators) 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: if grp.nelements == 0: continue - # FIXME: Should make matrices on device and cache them - diff_matrices = grp.diff_matrices() - diff_matrices_ary = np.empty(( + matrices = repr_op.matrices(grp) + + # FIXME: Should transfer matrices to device and cache them + matrices_ary = np.empty(( noperators, grp.nunit_nodes, grp.nunit_nodes)) 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, - diff_mat=diff_matrices_ary, + diff_mat=matrices_ary, result=grp.view(result), vec=grp.view(field)) return [(name, result[i]) for i, name in enumerate(insn.names)], [] diff --git a/grudge/models/advection.py b/grudge/models/advection.py index da920cc09b085894eef7fd2edc7e777b70dcb33c..8fda51a0a3b98a3a3ac04aea974cae7350904e33 100644 --- a/grudge/models/advection.py +++ b/grudge/models/advection.py @@ -88,41 +88,43 @@ class StrongAdvectionOperator(AdvectionOperatorBase): self.flux(pair)) return ( - -self.v.dot(sym.nabla(self.ambient_dim)*u) + - self.v.dot(sym.nabla(self.ambient_dim)*u) + sym.InverseMassOperator()( sym.FaceMassOperator()( 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): - def flux(self): - return self.weak_flux() + def flux(self, u): + return self.weak_flux(u) def sym_operator(self): - from grudge.symbolic import ( - Field, - BoundaryPair, - get_flux_operator, - make_stiffness_t, - InverseMassOperator, - RestrictToBoundary) - - u = Field("u") + u = sym.var("u") # boundary conditions ------------------------------------------------- - bc_in = Field("bc_in") - bc_out = RestrictToBoundary(self.outflow_tag)*u + bc_in = self.inflow_u + # bc_out = sym.interp("vol", self.outflow_tag)(u) - stiff_t = make_stiffness_t(self.dimensions) - m_inv = InverseMassOperator() + def flux(pair): + 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) - ( - flux_op(u) - + flux_op(BoundaryPair(u, bc_in, self.inflow_tag)) - + flux_op(BoundaryPair(u, bc_out, self.outflow_tag)) + # 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)) )) # }}} diff --git a/grudge/symbolic/operators.py b/grudge/symbolic/operators.py index 697592981a3fc4b16f518c4fa53a7a492de0eb61..dc2e4fa1afd8cf6bd91ff1faa8b8df7a34b06a46 100644 --- a/grudge/symbolic/operators.py +++ b/grudge/symbolic/operators.py @@ -214,10 +214,20 @@ class RefDiffOperatorBase(ElementwiseLinearOperator): class RefDiffOperator(RefDiffOperatorBase): mapper_method = intern("map_ref_diff") + @staticmethod + def matrices(element_group): + return element_group.diff_matrices() + class RefStiffnessTOperator(RefDiffOperatorBase): 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): class RefMassOperator(RefMassOperatorBase): @staticmethod def matrix(element_group): - import modepy as mp - return mp.mass_matrix( - element_group.basis(), - element_group.unit_nodes) + return element_group.mass_matrix() mapper_method = intern("map_ref_mass") diff --git a/test/test_grudge.py b/test/test_grudge.py index b4b6db456049816fd3319f414ebca5e21dfc6757..3372567408a29c3a3927619df8f6f5bf9ecd14b7 100644 --- a/test/test_grudge.py +++ b/test/test_grudge.py @@ -208,10 +208,11 @@ def test_2d_gauss_theorem(ctx_factory): ("rect2", [4, 8]), ("rect3", [4, 6]), ]) +@pytest.mark.parametrize("op_type", ["strong", "weak"]) @pytest.mark.parametrize("flux_type", ["upwind"]) @pytest.mark.parametrize("order", [3, 4, 5]) -def test_convergence_advec(ctx_factory, mesh_name, mesh_pars, flux_type, order, - visualize=False): +def test_convergence_advec(ctx_factory, mesh_name, mesh_pars, op_type, flux_type, + order, visualize=False): """Test whether 2D advection actually converges""" cl_ctx = cl.create_some_context() @@ -268,13 +269,20 @@ def test_convergence_advec(ctx_factory, mesh_name, mesh_pars, flux_type, order, -v.dot(x)/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) - 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)), flux_type=flux_type) bound_op = bind(discr, op.sym_operator()) + #print(bound_op) + #1/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, last_u = event.state_component 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)]) error_l2 = bind(discr,