Skip to content

Commit f958f69

Browse files
committed
fem: explicitly set use_canonical_quadrature_point_ordering=False for special node types
1 parent 31cca14 commit f958f69

File tree

3 files changed

+36
-21
lines changed

3 files changed

+36
-21
lines changed

tsfc/fem.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,18 @@
4646
class ContextBase(ProxyKernelInterface):
4747
"""Common UFL -> GEM translation context."""
4848

49-
keywords = ('ufl_cell',
50-
'fiat_cell',
51-
'integral_type',
52-
'integration_dim',
53-
'entity_ids',
54-
'argument_multiindices',
55-
'facetarea',
56-
'index_cache',
57-
'scalar_type')
49+
keywords = (
50+
'ufl_cell',
51+
'fiat_cell',
52+
'integral_type',
53+
'integration_dim',
54+
'entity_ids',
55+
'argument_multiindices',
56+
'facetarea',
57+
'index_cache',
58+
'scalar_type',
59+
'use_canonical_quadrature_point_ordering',
60+
)
5861

5962
def __init__(self, interface, **kwargs):
6063
ProxyKernelInterface.__init__(self, interface)
@@ -112,6 +115,9 @@ def translator(self):
112115

113116
@cached_property
114117
def use_canonical_quadrature_point_ordering(self):
118+
# Directly set use_canonical_quadrature_point_ordering = False in context
119+
# for translation of special nodes, e.g., CellVolume, FacetArea, CellOrigin, and CellVertices,
120+
# as quadrature point ordering is not relevant for those node types.
115121
return isinstance(self.fiat_cell, UFCHexahedron) and self.integral_type in ['exterior_facet', 'interior_facet']
116122

117123

@@ -161,6 +167,7 @@ def jacobian_at(self, point):
161167
expr = NegativeRestricted(expr)
162168
config = {"point_set": PointSingleton(point)}
163169
config.update(self.config)
170+
config.update(use_canonical_quadrature_point_ordering=False) # Not relevant.
164171
context = PointSetContext(**config)
165172
expr = self.preprocess(expr, context)
166173
return map_expr_dag(context.translator, expr)
@@ -173,6 +180,7 @@ def detJ_at(self, point):
173180
expr = NegativeRestricted(expr)
174181
config = {"point_set": PointSingleton(point)}
175182
config.update(self.config)
183+
config.update(use_canonical_quadrature_point_ordering=False) # Not relevant.
176184
context = PointSetContext(**config)
177185
expr = self.preprocess(expr, context)
178186
return map_expr_dag(context.translator, expr)
@@ -221,6 +229,7 @@ def physical_edge_lengths(self):
221229
expr = ufl.as_vector([ufl.sqrt(ufl.dot(expr[i, :], expr[i, :])) for i in range(num_edges)])
222230
config = {"point_set": PointSingleton(cell.make_points(sd, 0, sd+1)[0])}
223231
config.update(self.config)
232+
config.update(use_canonical_quadrature_point_ordering=False) # Not relevant.
224233
context = PointSetContext(**config)
225234
expr = self.preprocess(expr, context)
226235
return map_expr_dag(context.translator, expr)
@@ -243,6 +252,7 @@ def physical_points(self, point_set, entity=None):
243252
if entity is not None:
244253
config.update({name: getattr(self.interface, name)
245254
for name in ["integration_dim", "entity_ids"]})
255+
config.update(use_canonical_quadrature_point_ordering=False) # Not relevant.
246256
context = PointSetContext(**config)
247257
expr = self.preprocess(expr, context)
248258
mapped = map_expr_dag(context.translator, expr)
@@ -528,7 +538,7 @@ def translate_cellvolume(terminal, mt, ctx):
528538

529539
config = {name: getattr(ctx, name)
530540
for name in ["ufl_cell", "index_cache", "scalar_type"]}
531-
config.update(interface=interface, quadrature_degree=degree)
541+
config.update(interface=interface, quadrature_degree=degree, use_canonical_quadrature_point_ordering=False)
532542
expr, = compile_ufl(integrand, PointSetContext(**config), point_sum=True)
533543
return expr
534544

@@ -542,7 +552,7 @@ def translate_facetarea(terminal, mt, ctx):
542552
config = {name: getattr(ctx, name)
543553
for name in ["ufl_cell", "integration_dim", "scalar_type",
544554
"entity_ids", "index_cache"]}
545-
config.update(interface=ctx, quadrature_degree=degree)
555+
config.update(interface=ctx, quadrature_degree=degree, use_canonical_quadrature_point_ordering=False)
546556
expr, = compile_ufl(integrand, PointSetContext(**config), point_sum=True)
547557
return expr
548558

@@ -556,7 +566,7 @@ def translate_cellorigin(terminal, mt, ctx):
556566

557567
config = {name: getattr(ctx, name)
558568
for name in ["ufl_cell", "index_cache", "scalar_type"]}
559-
config.update(interface=ctx, point_set=point_set)
569+
config.update(interface=ctx, point_set=point_set, use_canonical_quadrature_point_ordering=False)
560570
context = PointSetContext(**config)
561571
return context.translator(expression)
562572

@@ -569,7 +579,7 @@ def translate_cell_vertices(terminal, mt, ctx):
569579

570580
config = {name: getattr(ctx, name)
571581
for name in ["ufl_cell", "index_cache", "scalar_type"]}
572-
config.update(interface=ctx, point_set=ps)
582+
config.update(interface=ctx, point_set=ps, use_canonical_quadrature_point_ordering=False)
573583
context = PointSetContext(**config)
574584
expr = context.translator(ufl_expr)
575585

tsfc/kernel_interface/common.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def compile_gem(self, ctx):
216216
# Let the kernel interface inspect the optimised IR to register
217217
# what kind of external data is required (e.g., cell orientations,
218218
# cell sizes, etc.).
219-
oriented, needs_cell_sizes, tabulations = self.register_requirements(expressions)
219+
oriented, needs_cell_sizes, tabulations, need_facet_orientation = self.register_requirements(expressions)
220220

221221
# Extract Variables that are actually used
222222
active_variables = gem.extract_type(expressions, gem.Variable)
@@ -227,7 +227,7 @@ def compile_gem(self, ctx):
227227
impero_c = impero_utils.compile_gem(assignments, index_ordering, remove_zeros=True)
228228
except impero_utils.NoopError:
229229
impero_c = None
230-
return impero_c, oriented, needs_cell_sizes, tabulations, active_variables
230+
return impero_c, oriented, needs_cell_sizes, tabulations, active_variables, need_facet_orientation
231231

232232
def fem_config(self):
233233
"""Return a dictionary used with fem.compile_ufl.
@@ -431,6 +431,7 @@ def check_requirements(ir):
431431
in one pass."""
432432
cell_orientations = False
433433
cell_sizes = False
434+
facet_orientation = False
434435
rt_tabs = {}
435436
for node in traversal(ir):
436437
if isinstance(node, gem.Variable):
@@ -440,7 +441,9 @@ def check_requirements(ir):
440441
cell_sizes = True
441442
elif node.name.startswith("rt_"):
442443
rt_tabs[node.name] = node.shape
443-
return cell_orientations, cell_sizes, tuple(sorted(rt_tabs.items()))
444+
elif node.name == "facet_orientation":
445+
facet_orientation = True
446+
return cell_orientations, cell_sizes, tuple(sorted(rt_tabs.items())), facet_orientation
444447

445448

446449
def prepare_constant(constant, number):

tsfc/kernel_interface/firedrake_loopy.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import loopy as lp
1313

14-
from tsfc import kernel_args, fem
14+
from tsfc import kernel_args
1515
from tsfc.finatinterface import create_element
1616
from tsfc.kernel_interface.common import KernelBuilderBase as _KernelBuilderBase, KernelBuilderMixin, get_index_names, check_requirements, prepare_coefficient, prepare_arguments, prepare_constant
1717
from tsfc.loopy import generate as generate_loopy
@@ -190,7 +190,7 @@ def set_coefficient_numbers(self, coefficient_numbers):
190190
def register_requirements(self, ir):
191191
"""Inspect what is referenced by the IR that needs to be
192192
provided by the kernel interface."""
193-
self.oriented, self.cell_sizes, self.tabulations = check_requirements(ir)
193+
self.oriented, self.cell_sizes, self.tabulations, _ = check_requirements(ir)
194194

195195
def set_output(self, o):
196196
"""Produce the kernel return argument"""
@@ -368,7 +368,7 @@ def construct_kernel(self, name, ctx, log=False):
368368
:arg log: bool if the Kernel should be profiled with Log events
369369
:returns: :class:`Kernel` object
370370
"""
371-
impero_c, oriented, needs_cell_sizes, tabulations, active_variables = self.compile_gem(ctx)
371+
impero_c, oriented, needs_cell_sizes, tabulations, active_variables, need_facet_orientation = self.compile_gem(ctx)
372372
if impero_c is None:
373373
return self.construct_empty_kernel(name)
374374
info = self.integral_data_info
@@ -418,8 +418,10 @@ def construct_kernel(self, name, ctx, log=False):
418418
elif info.integral_type in ["interior_facet", "interior_facet_vert"]:
419419
int_loopy_arg = lp.GlobalArg("facet", numpy.uint32, shape=(2,))
420420
args.append(kernel_args.InteriorFacetKernelArg(int_loopy_arg))
421-
# Will generalise this in the submesh PR.
422-
if fem.PointSetContext(**self.fem_config()).use_canonical_quadrature_point_ordering:
421+
# The submesh PR will introduce a robust mechanism to check if a Variable
422+
# is actually used in the final form of the expression, so there will be
423+
# no need to get "need_facet_orientation" from self.compile_gem().
424+
if need_facet_orientation:
423425
if info.integral_type == "exterior_facet":
424426
ext_ornt_loopy_arg = lp.GlobalArg("facet_orientation", gem.uint_type, shape=(1,))
425427
args.append(kernel_args.ExteriorFacetOrientationKernelArg(ext_ornt_loopy_arg))

0 commit comments

Comments
 (0)