@@ -345,8 +345,6 @@ def distance(alpha, beta):
345345
346346 def _tabulate (self , n , pts , order = 0 ):
347347 """A version of tabulate() that also works for a single point."""
348- from FIAT .hdiv_trace import TraceError
349- from FIAT .polynomial_set import mis
350348 pts = numpy .asarray (pts )
351349 unique = self .continuity is not None and order == 0
352350 cell_point_map = compute_cell_point_map (self .ref_el , pts , unique = unique )
@@ -357,26 +355,7 @@ def _tabulate(self, n, pts, order=0):
357355 return phis [0 ]
358356
359357 if self .ref_el .is_trace ():
360- parent = self .ref_el .get_parent ()
361- tdim = self .ref_el .get_spatial_dimension ()
362- gdim = parent .get_spatial_dimension ()
363- for cell in phis :
364- # Promote facet keys to cell keys
365- phi = phis [cell ][(0 ,) * tdim ]
366- # Raise TraceError on gradient tabulations
367- msg = "Gradients on trace elements are not well-defined."
368- phis [cell ] = {alpha : phi if sum (alpha ) == 0 else TraceError (msg )
369- for i in range (order + 1 )
370- for alpha in mis (gdim , i )}
371- if tdim == 0 and len (phis ) == 0 :
372- # Hack for TensorProduct HDivTrace: do not raise TraceError on the interval
373- for cell in parent .topology [gdim ]:
374- phis [cell ] = {(0 ,)* gdim : numpy .zeros (())}
375- elif sum (len (cell_point_map [cell ]) for cell in cell_point_map ) < len (pts ):
376- # Raise TraceError when interior points fail to be binned on facets
377- for cell in parent .topology [gdim ]:
378- msg = "The HDivTrace element can only be tabulated on facets."
379- phis [cell ] = {(0 ,)* gdim : TraceError (msg )}
358+ phis = trace_tabulation (self .ref_el , cell_point_map , order , pts , phis )
380359
381360 if pts .dtype == object :
382361 # If binning is undefined, scale by the characteristic function of each subcell
@@ -402,7 +381,7 @@ def _tabulate(self, n, pts, order=0):
402381 result = {}
403382 base_phi = tuple (phis .values ())[0 ]
404383 for alpha in base_phi :
405- if isinstance (base_phi [alpha ], TraceError ):
384+ if isinstance (base_phi [alpha ], Exception ):
406385 result [alpha ] = base_phi [alpha ]
407386 continue
408387 dtype = base_phi [alpha ].dtype
@@ -723,7 +702,10 @@ def compute_cell_point_map(ref_el, pts, unique=True, tol=1E-12):
723702 return {cell : Ellipsis for cell in sorted (top [sd ])}
724703
725704 # The distance to the nearest cell is equal to the distance to the parent cell
726- best = ref_el .get_parent ().distance_to_point_l1 (pts , rescale = True )
705+ parent = ref_el
706+ while parent .get_parent () is not None :
707+ parent = parent .get_parent ()
708+ best = parent .distance_to_point_l1 (pts , rescale = True )
727709 tol = best + tol
728710
729711 cell_point_map = {}
@@ -779,3 +761,30 @@ def compute_partition_of_unity(ref_el, pt, unique=True, tol=1E-12):
779761 mult = sum (masks )
780762 masks = [m / mult for m in masks ]
781763 return masks
764+
765+
766+ def trace_tabulation (ref_el , cell_point_map , order , pts , phis ):
767+ """Lift trace tabulations into the cells and raise TraceError on invalid tabulations."""
768+ from FIAT .polynomial_set import mis
769+ from FIAT .hdiv_trace import TraceError
770+ parent = ref_el .get_parent ()
771+ tdim = ref_el .get_spatial_dimension ()
772+ gdim = parent .get_spatial_dimension ()
773+ facet_key = (0 , ) * tdim
774+ cell_key = (0 , ) * gdim
775+
776+ for cell in phis :
777+ # Lift facet keys to cell keys
778+ phi = phis [cell ][facet_key ]
779+ # Raise TraceError on gradient tabulations
780+ msg = "Gradients on trace elements are not well-defined."
781+ phis [cell ] = {alpha : phi if sum (alpha ) == 0 else TraceError (msg )
782+ for i in range (order + 1 )
783+ for alpha in mis (gdim , i )}
784+
785+ if sum (len (cell_point_map [cell ]) for cell in cell_point_map ) < len (pts ):
786+ # Raise TraceError when interior points fail to be binned on facets
787+ for cell in parent .topology [gdim ]:
788+ msg = "The HDivTrace element can only be tabulated on facets."
789+ phis [cell ] = {cell_key : TraceError (msg )}
790+ return phis
0 commit comments