From e7470548f16153e4df148e9cba3388dfa0926df5 Mon Sep 17 00:00:00 2001 From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de> Date: Tue, 31 Jan 2017 16:54:24 +0100 Subject: [PATCH] Implement handlers to allow generation of correct penalty term --- .../convection_diffusion/conv_diff_dg.ufl | 14 ++++++--- applications/poisson_dg/poisson_dg.ufl | 14 ++++++--- python/dune/perftool/loopy/target.py | 2 +- python/dune/perftool/pdelab/__init__.py | 8 +++++ python/dune/perftool/pdelab/geometry.py | 30 +++++++++++++++++++ python/dune/perftool/ufl/preprocess.py | 18 +++++------ python/dune/perftool/ufl/visitor.py | 16 ++++++++++ test/poisson/opcount_poisson_dg.ufl | 12 +++++--- test/poisson/poisson_dg.ufl | 16 ++++++---- test/poisson/poisson_dg_neumann.ufl | 16 ++++++---- test/poisson/poisson_dg_tensor.ufl | 16 ++++++---- 11 files changed, 124 insertions(+), 38 deletions(-) diff --git a/applications/convection_diffusion/conv_diff_dg.ufl b/applications/convection_diffusion/conv_diff_dg.ufl index 38e8dc73..80e92055 100644 --- a/applications/convection_diffusion/conv_diff_dg.ufl +++ b/applications/convection_diffusion/conv_diff_dg.ufl @@ -1,3 +1,4 @@ +dim = 3 x = SpatialCoordinate(cell) g = x[0]*x[0] + x[1]*x[1] + x[2]*x[2] @@ -13,17 +14,22 @@ v = TestFunction(V) n = FacetNormal(cell)('+') -gamma = 1.0 +alpha = 1.0 +h_ext = CellVolume(cell) / FacetArea(cell) +gamma_ext = (alpha * degree * (degree + dim - 1)) / h_ext +h_int = Min(CellVolume(cell)('+'), CellVolume(cell)('-')) / FacetArea(cell) +gamma_int = (alpha * degree * (degree + dim - 1)) / h_int + theta = -1.0 r = (inner(A*grad(u), grad(v)) + (c*u-f)*v)*dx \ + inner(n, A*avg(grad(u)))*jump(v)*dS \ - + gamma*jump(u)*jump(v)*dS \ + + gamma_int*jump(u)*jump(v)*dS \ + theta*jump(u)*inner(A*avg(grad(v)), n)*dS \ - inner(n, A*grad(u))*v*ds \ - + gamma*u*v*ds \ + + gamma_ext*u*v*ds \ - theta*u*inner(A*grad(v), n)*ds \ + theta*g*inner(A*grad(v), n)*ds \ - - gamma*g*v*ds + - gamma_ext*g*v*ds forms = [r] diff --git a/applications/poisson_dg/poisson_dg.ufl b/applications/poisson_dg/poisson_dg.ufl index 53636053..7d532811 100644 --- a/applications/poisson_dg/poisson_dg.ufl +++ b/applications/poisson_dg/poisson_dg.ufl @@ -1,3 +1,4 @@ +dim = 3 x = SpatialCoordinate(cell) f = -6. g = x[0]*x[0] + x[1]*x[1] + x[2]*x[2] @@ -9,18 +10,23 @@ v = TestFunction(V) n = FacetNormal(cell)('+') -gamma = 1.0 +alpha = 1.0 +h_ext = CellVolume(cell) / FacetArea(cell) +gamma_ext = (alpha * degree * (degree + dim - 1)) / h_ext +h_int = Min(CellVolume(cell)('+'), CellVolume(cell)('-')) / FacetArea(cell) +gamma_int = (alpha * degree * (degree + dim - 1)) / h_int + theta = 1.0 r = inner(grad(u), grad(v))*dx \ + inner(n, avg(grad(u)))*jump(v)*dS \ - + gamma*jump(u)*jump(v)*dS \ + + gamma_int*jump(u)*jump(v)*dS \ + theta*jump(u)*inner(avg(grad(v)), n)*dS \ - inner(n, grad(u))*v*ds \ - + gamma*u*v*ds \ + + gamma_ext*u*v*ds \ - theta*u*inner(grad(v), n)*ds \ - f*v*dx \ + theta*g*inner(grad(v), n)*ds \ - - gamma*g*v*ds + - gamma_ext*g*v*ds forms = [r] diff --git a/python/dune/perftool/loopy/target.py b/python/dune/perftool/loopy/target.py index 9427a401..6ef27648 100644 --- a/python/dune/perftool/loopy/target.py +++ b/python/dune/perftool/loopy/target.py @@ -118,7 +118,7 @@ class DuneCExpressionToCodeMapper(CExpressionToCodeMapper): result = self.rec(children.pop(), PREC_NONE) while children: - result = "std::%s(%s, %s)" % (what, + result = "%s(%s, %s)" % (what, self.rec(children.pop(), PREC_NONE), result) diff --git a/python/dune/perftool/pdelab/__init__.py b/python/dune/perftool/pdelab/__init__.py index 8529eb1e..dcc17068 100644 --- a/python/dune/perftool/pdelab/__init__.py +++ b/python/dune/perftool/pdelab/__init__.py @@ -11,6 +11,8 @@ from dune.perftool.pdelab.basis import (pymbolic_basis, pymbolic_reference_gradient, ) from dune.perftool.pdelab.geometry import (dimension_iname, + name_cell_volume, + name_facet_area, name_facet_jacobian_determinant, name_jacobian_determinant, name_jacobian_inverse_transposed, @@ -112,6 +114,12 @@ class PDELabInterface(object): def name_unit_outer_normal(self): return name_unit_outer_normal() + def name_cell_volume(self, restriction): + return name_cell_volume(restriction) + + def name_facet_area(self): + return name_facet_area() + # # Quadrature related generator functions # diff --git a/python/dune/perftool/pdelab/geometry.py b/python/dune/perftool/pdelab/geometry.py index b66f58fc..ce080eba 100644 --- a/python/dune/perftool/pdelab/geometry.py +++ b/python/dune/perftool/pdelab/geometry.py @@ -405,3 +405,33 @@ def to_global(local): name = get_pymbolic_basename(local) + "_global" apply_to_global_transformation(name, local) return prim.Variable(name) + + +def define_cell_volume(name, restriction): + geo = name_cell_geometry(restriction) + temporary_variable(name, shape=()) + code = "{} = {}.volume();".format(name, geo) + return quadrature_preamble(code, + assignees=frozenset({name}), + ) + + +def name_cell_volume(restriction): + name = restricted_name("volume", restriction) + define_cell_volume(name, restriction) + return name + + +def define_facet_area(name): + geo = name_intersection_geometry() + temporary_variable(name, shape=()) + code = "{} = {}.volume();".format(name, geo) + return quadrature_preamble(code, + assignees=frozenset({name}), + ) + + +def name_facet_area(): + name = "area" + define_facet_area(name) + return name diff --git a/python/dune/perftool/ufl/preprocess.py b/python/dune/perftool/ufl/preprocess.py index 540300bb..913bf5da 100644 --- a/python/dune/perftool/ufl/preprocess.py +++ b/python/dune/perftool/ufl/preprocess.py @@ -1,22 +1,20 @@ """ Preprocessing algorithms for UFL forms """ +import ufl.classes as uc -def preprocess_form(form): - from ufl.classes import (FacetJacobianDeterminant, - FacetNormal, - JacobianDeterminant, - JacobianInverse, - ) +def preprocess_form(form): from ufl.algorithms import compute_form_data formdata = compute_form_data(form, do_apply_function_pullbacks=True, do_apply_geometry_lowering=True, do_apply_integral_scaling=True, - preserve_geometry_types=(FacetJacobianDeterminant, - FacetNormal, - JacobianDeterminant, - JacobianInverse, + preserve_geometry_types=(uc.CellVolume, + uc.FacetArea, + uc.FacetJacobianDeterminant, + uc.FacetNormal, + uc.JacobianDeterminant, + uc.JacobianInverse, ) ) diff --git a/python/dune/perftool/ufl/visitor.py b/python/dune/perftool/ufl/visitor.py index 1ba817c8..de92f3a4 100644 --- a/python/dune/perftool/ufl/visitor.py +++ b/python/dune/perftool/ufl/visitor.py @@ -265,6 +265,12 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker): raise NotImplementedError("Power function not really implemented") + def max_value(self, o): + return prim.Max(tuple(self.call(op) for op in o.ufl_operands)) + + def min_value(self, o): + return prim.Min(tuple(self.call(op) for op in o.ufl_operands)) + # # Handler for conditionals, use pymbolic base implementation # @@ -360,6 +366,16 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker): def facet_jacobian_determinant(self, o): return Variable(self.interface.name_facet_jacobian_determinant()) + def cell_volume(self, o): + restriction = self.restriction + if self.measure == 'exterior_facet': + restriction = Restriction.NEGATIVE + + return prim.Variable(self.interface.name_cell_volume(restriction)) + + def facet_area(self, o): + return prim.Variable(self.interface.name_facet_area()) + # # Equality/Hashability of the visitor # In order to pass this visitor into (cached) generator functions, it is beneficial diff --git a/test/poisson/opcount_poisson_dg.ufl b/test/poisson/opcount_poisson_dg.ufl index 3ced1b82..ed537bc9 100644 --- a/test/poisson/opcount_poisson_dg.ufl +++ b/test/poisson/opcount_poisson_dg.ufl @@ -11,20 +11,24 @@ v = TestFunction(V) n = FacetNormal(cell)('+') # penalty factor -gamma = 1.0 +alpha = 1.0 +h_ext = CellVolume(cell) / FacetArea(cell) +gamma_ext = (alpha * degree * (degree + dim - 1)) / h_ext +h_int = Min(CellVolume(cell)('+'), CellVolume(cell)('-')) / FacetArea(cell) +gamma_int = (alpha * degree * (degree + dim - 1)) / h_int # SIPG: -1.0, IIPG: 0.0, NIPG: 1.0 theta = 1.0 r = inner(grad(u), grad(v))*dx \ + inner(n, avg(grad(u)))*jump(v)*dS \ - + gamma*jump(u)*jump(v)*dS \ + + gamma_int*jump(u)*jump(v)*dS \ - theta*jump(u)*inner(avg(grad(v)), n)*dS \ - inner(n, grad(u))*v*ds \ - + gamma*u*v*ds \ + + gamma_ext*u*v*ds \ + theta*u*inner(grad(v), n)*ds \ - f*v*dx \ - theta*g*inner(grad(v), n)*ds \ - - gamma*g*v*ds + - gamma_ext*g*v*ds forms = [r] diff --git a/test/poisson/poisson_dg.ufl b/test/poisson/poisson_dg.ufl index daf2793e..b8ad0425 100644 --- a/test/poisson/poisson_dg.ufl +++ b/test/poisson/poisson_dg.ufl @@ -1,11 +1,13 @@ cell = triangle +degree = 1 +dim = 2 x = SpatialCoordinate(cell) c = (0.5-x[0])**2 + (0.5-x[1])**2 g = exp(-1.*c) f = 4*(1.-c)*g -V = FiniteElement("DG", cell, 1) +V = FiniteElement("DG", cell, degree) u = TrialFunction(V) v = TestFunction(V) @@ -13,20 +15,24 @@ v = TestFunction(V) n = FacetNormal(cell)('+') # penalty factor -gamma = 1.0 +alpha = 1.0 +h_ext = CellVolume(cell) / FacetArea(cell) +gamma_ext = (alpha * degree * (degree + dim - 1)) / h_ext +h_int = Min(CellVolume(cell)('+'), CellVolume(cell)('-')) / FacetArea(cell) +gamma_int = (alpha * degree * (degree + dim - 1)) / h_int # SIPG: -1.0, IIPG: 0.0, NIPG: 1.0 theta = 1.0 r = inner(grad(u), grad(v))*dx \ + inner(n, avg(grad(u)))*jump(v)*dS \ - + gamma*jump(u)*jump(v)*dS \ + + gamma_int*jump(u)*jump(v)*dS \ - theta*jump(u)*inner(avg(grad(v)), n)*dS \ - inner(n, grad(u))*v*ds \ - + gamma*u*v*ds \ + + gamma_ext*u*v*ds \ + theta*u*inner(grad(v), n)*ds \ - f*v*dx \ - theta*g*inner(grad(v), n)*ds \ - - gamma*g*v*ds + - gamma_ext*g*v*ds forms = [r] diff --git a/test/poisson/poisson_dg_neumann.ufl b/test/poisson/poisson_dg_neumann.ufl index 1dd15d4f..884787e6 100644 --- a/test/poisson/poisson_dg_neumann.ufl +++ b/test/poisson/poisson_dg_neumann.ufl @@ -1,3 +1,5 @@ +dim = 3 +degree = 1 cell = triangle x = SpatialCoordinate(cell) @@ -8,7 +10,7 @@ sgn = conditional(x[1] > 0.5, 1., -1.) j = -2.*sgn*(x[1]-0.5)*g bctype = conditional(Or(x[1]<1e-8, x[1]>1.-1e-8), 0, 1) -V = FiniteElement("DG", cell, 1) +V = FiniteElement("DG", cell, degree) u = TrialFunction(V) v = TestFunction(V) @@ -18,21 +20,25 @@ n = FacetNormal(cell)('+') ds = ds(subdomain_data=bctype) # penalty factor -gamma = 1.0 +alpha = 1.0 +h_ext = CellVolume(cell) / FacetArea(cell) +gamma_ext = (alpha * degree * (degree + dim - 1)) / h_ext +h_int = Min(CellVolume(cell)('+'), CellVolume(cell)('-')) / FacetArea(cell) +gamma_int = (alpha * degree * (degree + dim - 1)) / h_int # SIPG: -1.0, IIPG: 0.0, NIPG: 1.0 theta = 1.0 r = inner(grad(u), grad(v))*dx \ + inner(n, avg(grad(u)))*jump(v)*dS \ - + gamma*jump(u)*jump(v)*dS \ + + gamma_int*jump(u)*jump(v)*dS \ - theta*jump(u)*inner(avg(grad(v)), n)*dS \ - inner(n, grad(u))*v*ds(1) \ - + gamma*u*v*ds(1) \ + + gamma_ext*u*v*ds(1) \ + theta*u*inner(grad(v), n)*ds(1) \ - f*v*dx \ - theta*g*inner(grad(v), n)*ds(1) \ - - gamma*g*v*ds(1) \ + - gamma_ext*g*v*ds(1) \ - j*v*ds(0) forms = [r] diff --git a/test/poisson/poisson_dg_tensor.ufl b/test/poisson/poisson_dg_tensor.ufl index d84cebf6..1ae0139b 100644 --- a/test/poisson/poisson_dg_tensor.ufl +++ b/test/poisson/poisson_dg_tensor.ufl @@ -1,3 +1,5 @@ +dim = 2 +degree = 1 cell = quadrilateral x = SpatialCoordinate(cell) @@ -8,7 +10,7 @@ g = x[0]**2 + x[1]**2 c = 8. f = -4. -V = FiniteElement("DG", cell, 1) +V = FiniteElement("DG", cell, degree) u = TrialFunction(V) v = TestFunction(V) @@ -16,20 +18,24 @@ v = TestFunction(V) n = FacetNormal(cell)('+') # penalty factor -gamma = 1.0 +alpha = 1.0 +h_ext = CellVolume(cell) / FacetArea(cell) +gamma_ext = (alpha * degree * (degree + dim - 1)) / h_ext +h_int = Min(CellVolume(cell)('+'), CellVolume(cell)('-')) / FacetArea(cell) +gamma_int = (alpha * degree * (degree + dim - 1)) / h_int # SIPG: -1.0, IIPG: 0.0, NIPG: 1.0 theta = 1.0 r = (inner(A*grad(u), grad(v)) + c*u*v)*dx \ + inner(n, A*avg(grad(u)))*jump(v)*dS \ - + gamma*jump(u)*jump(v)*dS \ + + gamma_int*jump(u)*jump(v)*dS \ - theta*jump(u)*inner(A*avg(grad(v)), n)*dS \ - inner(n, A*grad(u))*v*ds \ - + gamma*u*v*ds \ + + gamma_ext*u*v*ds \ + theta*u*inner(A*grad(v), n)*ds \ - f*v*dx \ - theta*g*inner(A*grad(v), n)*ds \ - - gamma*g*v*ds + - gamma_ext*g*v*ds forms = [r] -- GitLab