diff --git a/examples/advection/var-velocity.py b/examples/advection/var-velocity.py
index ddc7535288cd82c1bbc56cb8decd9b0644cea73a..0a69967e8613adc76a9ff1d93ba02db90fb2dc9a 100644
--- a/examples/advection/var-velocity.py
+++ b/examples/advection/var-velocity.py
@@ -37,12 +37,13 @@ def main(write_output=True, order=4):
dim = 2
+ n_divs = 15
from meshmode.mesh.generation import generate_regular_rect_mesh
mesh = generate_regular_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5),
- n=(15, 15), order=order)
+ n=(n_divs, n_divs), order=order)
- dt_factor = 4
- h = 1/20
+ dt_factor = 5
+ h = 1/n_divs
discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order)
diff --git a/examples/quad/flux_quad.py b/examples/quad/flux_quad.py
new file mode 100644
index 0000000000000000000000000000000000000000..3d7f9a322d39176626f39bd1ea19267e0d42a43a
--- /dev/null
+++ b/examples/quad/flux_quad.py
@@ -0,0 +1,91 @@
+# Copyright (C) 2007 Andreas Kloeckner
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+
+import numpy as np
+import pyopencl as cl # noqa
+import pyopencl.array # noqa
+import pyopencl.clmath # noqa
+
+import pytest # noqa
+
+from pyopencl.tools import ( # noqa
+ pytest_generate_tests_for_pyopencl as pytest_generate_tests)
+
+import logging
+logger = logging.getLogger(__name__)
+
+from grudge import sym, bind, DGDiscretizationWithBoundaries
+
+import numpy.linalg as la
+
+
+
+
+def main(order=1):
+ cl_ctx = cl.create_some_context()
+ queue = cl.CommandQueue(cl_ctx)
+
+ dim = 2
+
+
+ from meshmode.mesh.generation import n_gon, generate_regular_rect_mesh
+ #mesh = n_gon(3,np.array([0.1,0.2,0.4,0.5,0.6,0.7,0.9]))
+ mesh = generate_regular_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5),
+ n=(3, 3), order=7)
+
+
+
+
+ pquad_dd = sym.DOFDesc("vol", "product")
+
+ discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order, quad_min_degrees={"product": 2 * order} )
+
+
+ magic_thing = sym.DOFDesc(sym.FACE_RESTR_ALL, "product")
+ #magic_thing = sym.DOFDesc(sym.FACE_RESTR_ALL)
+ def fluxy_stuff(u):
+ return sym.interp(u.dd, magic_thing)(u.int)
+
+
+ ones = bind(discr, sym.nodes(dim)[0] / sym.nodes(dim)[0])(queue, t=0)
+ nds = sym.nodes(dim)
+ op = sym.FaceMassOperator(magic_thing, "vol")(fluxy_stuff(sym.int_tpair(nds, "product")))
+ #op = (sym.int_tpair(nds, "product").int)
+ #op = sym.FaceMassOperator()(fluxy_stuff(sym.int_tpair(nds)))
+ print(op)
+
+ print(sym.pretty(op))
+ u = bind(discr, op)(queue, t=0)
+
+
+ print(u)
+
+
+
+
+ #vis.write_vtk_file("fld-000o.vtu", [ ("u", o) ])
+ #vis.write_vtk_file("fld-000u.vtu", [ ("u", u) ])
+
+
+
+
+
+
+
+if __name__ == "__main__":
+ main(4)
+
+
diff --git a/examples/quad/mass_quad.py b/examples/quad/mass_quad.py
new file mode 100644
index 0000000000000000000000000000000000000000..05c306bd9af5bd1838a2b09e325c663163f425b5
--- /dev/null
+++ b/examples/quad/mass_quad.py
@@ -0,0 +1,90 @@
+# Copyright (C) 2007 Andreas Kloeckner
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+
+import numpy as np
+import pyopencl as cl # noqa
+import pyopencl.array # noqa
+import pyopencl.clmath # noqa
+
+import pytest # noqa
+
+from pyopencl.tools import ( # noqa
+ pytest_generate_tests_for_pyopencl as pytest_generate_tests)
+
+import logging
+logger = logging.getLogger(__name__)
+
+from grudge import sym, bind, DGDiscretizationWithBoundaries
+
+import numpy.linalg as la
+
+
+
+
+def main(order=1):
+ cl_ctx = cl.create_some_context()
+ queue = cl.CommandQueue(cl_ctx)
+
+ dim = 2
+
+
+ from meshmode.mesh.generation import n_gon, generate_regular_rect_mesh
+ #mesh = n_gon(3,np.array([0.1,0.2,0.4,0.5,0.6,0.7,0.9]))
+ mesh = generate_regular_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5),
+ n=(3, 3), order=7)
+
+
+
+
+ pquad_dd = sym.DOFDesc("vol", "product")
+ to_pquad = sym.interp("vol", pquad_dd)
+
+ def f(x):
+ x = x[0] / x[0]
+ #return sym.MassOperator()(x)
+ return sym.MassOperator(pquad_dd, "vol")(to_pquad(x))
+ #return np.dot(from_pquad_stiffness_t, to_pquad(x))
+ #return sym.interp("vol", pquad_dd)(sym.sin(3*x[0]))
+
+ discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order, quad_min_degrees={"product": 2 * order} )
+
+
+
+
+
+
+
+ ones = bind(discr, sym.nodes(dim)[0] / sym.nodes(dim)[0])(queue, t=0)
+ u = bind(discr, f(sym.nodes(dim)))(queue, t=0)
+
+ print(np.dot(ones.T, u))
+
+
+
+
+ #vis.write_vtk_file("fld-000o.vtu", [ ("u", o) ])
+ #vis.write_vtk_file("fld-000u.vtu", [ ("u", u) ])
+
+
+
+
+
+
+
+if __name__ == "__main__":
+ main(4)
+
+
diff --git a/examples/quad/quad.py b/examples/quad/quad.py
new file mode 100644
index 0000000000000000000000000000000000000000..67c41fa234fe939af00af64c022d3979035f319d
--- /dev/null
+++ b/examples/quad/quad.py
@@ -0,0 +1,80 @@
+# Copyright (C) 2007 Andreas Kloeckner
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+
+import numpy as np
+import pyopencl as cl # noqa
+import pyopencl.array # noqa
+import pyopencl.clmath # noqa
+
+import pytest # noqa
+
+from pyopencl.tools import ( # noqa
+ pytest_generate_tests_for_pyopencl as pytest_generate_tests)
+
+import logging
+logger = logging.getLogger(__name__)
+
+from grudge import sym, bind, DGDiscretizationWithBoundaries
+
+import numpy.linalg as la
+
+
+
+
+def main(order=1):
+ cl_ctx = cl.create_some_context()
+ queue = cl.CommandQueue(cl_ctx)
+
+ dim = 2
+
+
+ from meshmode.mesh.generation import n_gon, generate_regular_rect_mesh
+ #mesh = n_gon(3,np.array([0.1,0.2,0.4,0.5,0.6,0.7,0.9]))
+ mesh = generate_regular_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5),
+ n=(3, 3), order=7)
+
+
+
+
+ pquad_dd = sym.DOFDesc("vol", "product")
+
+ def f(x):
+ #return sym.sin(3*x[0])
+ return sym.interp("vol", pquad_dd)(sym.sin(3*x[0]))
+
+ discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order, quad_min_degrees={"product": 2 * order} )
+
+ u = bind(discr, f(sym.nodes(dim)))(queue, t=0)
+
+
+
+ from meshmode.discretization.visualization import make_visualizer
+ #vis = make_visualizer(queue, discr.quad_volume_discr['product'], 2*order)
+ #vis = make_visualizer(queue, discr.volume_discr, order)
+
+ #vis.write_vtk_file("fld-000.vtu", [ ("u", u) ])
+ print(u)
+
+
+
+
+
+
+
+if __name__ == "__main__":
+ main(4)
+
+
diff --git a/examples/quad/stiffness_quad.py b/examples/quad/stiffness_quad.py
new file mode 100644
index 0000000000000000000000000000000000000000..ff334c4ec0073f1640ad936475ae96088797ecc6
--- /dev/null
+++ b/examples/quad/stiffness_quad.py
@@ -0,0 +1,99 @@
+# Copyright (C) 2007 Andreas Kloeckner
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+
+import numpy as np
+import pyopencl as cl # noqa
+import pyopencl.array # noqa
+import pyopencl.clmath # noqa
+
+import pytest # noqa
+
+from pyopencl.tools import ( # noqa
+ pytest_generate_tests_for_pyopencl as pytest_generate_tests)
+
+import logging
+logger = logging.getLogger(__name__)
+
+from grudge import sym, bind, DGDiscretizationWithBoundaries
+
+import numpy.linalg as la
+
+
+
+
+def main(order=1):
+ cl_ctx = cl.create_some_context()
+ queue = cl.CommandQueue(cl_ctx)
+
+ dim = 2
+
+
+ from meshmode.mesh.generation import n_gon, generate_regular_rect_mesh
+ #mesh = n_gon(3,np.array([0.1,0.2,0.4,0.5,0.6,0.7,0.9]))
+ mesh = generate_regular_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5),
+ n=(3, 3), order=7)
+
+
+
+
+ pquad_dd = sym.DOFDesc("vol", "product")
+ to_pquad = sym.interp("vol", pquad_dd)
+ from_pquad_stiffness_t = sym.stiffness_t(dim, pquad_dd, "vol")
+ from_pquad_mass = sym.MassOperator()
+
+ def lin(x):
+ return x[0]
+
+ def non_lin(x):
+ return x[1] * x[0] * x[0] + 3* x[0] * x[0] - 4
+
+ def f(x, fun):
+ #return sym.MassOperator()(x)
+ #return np.dot(sym.stiffness_t(2), to_pquad(fun(x)))
+ return np.dot(from_pquad_stiffness_t, fun(to_pquad(x)))
+
+ def reg(x, fun):
+ #return sym.MassOperator()(x)
+ #return np.dot(sym.stiffness_t(2), to_pquad(fun(x)))
+ return np.dot(sym.stiffness_t(2), fun(x))
+
+ discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order, quad_min_degrees={"product": 2 * order} )
+
+
+ #ones = bind(discr, sym.nodes(dim)[0] / sym.nodes(dim)[0])(queue, t=0)
+ nds = sym.nodes(dim)
+ #u = bind(discr, to_pquad(nds))(queue, t=0)
+ #u = bind(discr, reg(nds, lin))(queue, t=0)
+ u = bind(discr, f(nds, lin))(queue, t=0)
+
+ print(u)
+
+
+
+
+ #vis.write_vtk_file("fld-000o.vtu", [ ("u", o) ])
+ #vis.write_vtk_file("fld-000u.vtu", [ ("u", u) ])
+
+
+
+
+
+
+
+if __name__ == "__main__":
+ main(4)
+
+
diff --git a/grudge/discretization.py b/grudge/discretization.py
index a1ca6303ce40f787ddce458438c88e983b8b94d3..05360ecdfbe5a53d254b29c077eda7f07e75f211 100644
--- a/grudge/discretization.py
+++ b/grudge/discretization.py
@@ -82,8 +82,7 @@ class DGDiscretizationWithBoundaries(DiscretizationBase):
if dd.is_volume():
if qtag is not sym.QTAG_NONE:
- # FIXME
- raise NotImplementedError("quadrature")
+ return self._quad_volume_discr(qtag)
return self._volume_discr
elif dd.domain_tag is sym.FACE_RESTR_ALL:
@@ -120,6 +119,12 @@ class DGDiscretizationWithBoundaries(DiscretizationBase):
self._boundary_to_quad_connection(
to_dd.domain_tag.tag, to_dd.quadrature_tag)])
+ elif to_dd.is_volume():
+ from meshmode.discretization.connection import make_same_mesh_connection
+ to_discr = self._quad_volume_discr(to_dd.quadrature_tag)
+ from_discr = self._volume_discr
+ return make_same_mesh_connection(to_discr, from_discr)
+
else:
raise ValueError("cannot interpolate from volume to: " + str(to_dd))
@@ -130,6 +135,24 @@ class DGDiscretizationWithBoundaries(DiscretizationBase):
raise ValueError(
"cannot interpolate from interior faces to: "
+ str(to_dd))
+ elif from_dd.domain_tag is sym.FACE_RESTR_ALL:
+ if to_dd.domain_tag is sym.FACE_RESTR_ALL and qtag is not sym.QTAG_NONE:
+ from meshmode.discretization.connection import make_face_restriction, FACE_RESTR_ALL
+ return make_face_restriction(
+ self._all_faces_discr(),
+ self.group_factory_for_quadrature_tag(qtag),
+ FACE_RESTR_ALL,
+
+ # FIXME: This will need to change as soon as we support
+ # pyramids or other elements with non-identical face
+ # types.
+ per_face_groups=False)
+
+ #return self._all_faces_connection(None, qtag)
+ else:
+ raise ValueError(
+ "cannot interpolate from interior faces to: "
+ + str(to_dd))
elif from_dd.is_boundary():
if to_dd.domain_tag is sym.FACE_RESTR_ALL and qtag is sym.QTAG_NONE:
@@ -155,7 +178,7 @@ class DGDiscretizationWithBoundaries(DiscretizationBase):
QuadratureSimplexGroupFactory
if quadrature_tag is not sym.QTAG_NONE:
- return QuadratureSimplexGroupFactory(order=self.order)
+ return QuadratureSimplexGroupFactory(order=self.quad_min_degrees[quadrature_tag])
else:
return PolynomialWarpAndBlendGroupFactory(order=self.order)
@@ -259,7 +282,7 @@ class DGDiscretizationWithBoundaries(DiscretizationBase):
return self._all_faces_volume_connection(quadrature_tag).to_discr
@memoize_method
- def _all_faces_connection(self, boundary_tag):
+ def _all_faces_connection(self, boundary_tag, to_qtag=None):
"""Return a
:class:`meshmode.discretization.connection.DiscretizationConnection`
that goes from either
@@ -277,7 +300,7 @@ class DGDiscretizationWithBoundaries(DiscretizationBase):
else:
faces_conn = self._boundary_connection(boundary_tag)
- return make_face_to_all_faces_embedding(faces_conn, self._all_faces_discr())
+ return make_face_to_all_faces_embedding(faces_conn, self._all_faces_discr(to_qtag))
# }}}
diff --git a/grudge/execution.py b/grudge/execution.py
index e4aebe5ca18b495acf4e608ff9f4cdfd218f57b1..40dcb19a1178239b6b617dceb0b676d3a85fd468 100644
--- a/grudge/execution.py
+++ b/grudge/execution.py
@@ -198,36 +198,42 @@ class ExecutionMapper(mappers.Evaluator,
knl = lp.make_kernel(
"""{[k,i,j]:
0<=k