From 7982284d48bbc8702fd6438b858e4e0c5ff3121a Mon Sep 17 00:00:00 2001 From: Bogdan Enache Date: Mon, 4 Dec 2017 10:26:37 -0600 Subject: [PATCH] In the middle of fluxy quadratures, 2 --- examples/advection/var-velocity.py | 7 ++- examples/quad/flux_quad.py | 91 +++++++++++++++++++++++++++ examples/quad/mass_quad.py | 90 +++++++++++++++++++++++++++ examples/quad/quad.py | 80 ++++++++++++++++++++++++ examples/quad/stiffness_quad.py | 99 ++++++++++++++++++++++++++++++ grudge/discretization.py | 33 ++++++++-- grudge/execution.py | 59 +++++++++++------- grudge/models/advection.py | 2 +- grudge/symbolic/operators.py | 85 ++++++++++++++++++++----- grudge/symbolic/primitives.py | 11 +++- 10 files changed, 505 insertions(+), 52 deletions(-) create mode 100644 examples/quad/flux_quad.py create mode 100644 examples/quad/mass_quad.py create mode 100644 examples/quad/quad.py create mode 100644 examples/quad/stiffness_quad.py diff --git a/examples/advection/var-velocity.py b/examples/advection/var-velocity.py index ddc75352..0a69967e 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 00000000..3d7f9a32 --- /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 00000000..05c306bd --- /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 00000000..67c41fa2 --- /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 00000000..ff334c4e --- /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 a1ca6303..05360ecd 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 e4aebe5c..40dcb19a 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