|
12 | 12 | from firedrake import functionspaceimpl
|
13 | 13 | from firedrake import function
|
14 | 14 | from firedrake.adjoint_utils import annotate_project
|
15 |
| -from finat import HDivTrace |
16 | 15 |
|
17 | 16 |
|
18 | 17 | __all__ = ['project', 'Projector']
|
@@ -164,24 +163,25 @@ def __init__(
|
164 | 163 | self.form_compiler_parameters = form_compiler_parameters
|
165 | 164 | self.bcs = bcs
|
166 | 165 | self.constant_jacobian = constant_jacobian
|
167 |
| - try: |
168 |
| - element = self.target.function_space().finat_element |
169 |
| - is_dg = element.entity_dofs() == element.entity_closure_dofs() |
170 |
| - is_variable_layers = self.target.function_space().mesh().variable_layers |
171 |
| - except AttributeError: |
172 |
| - # Mixed space |
173 |
| - is_dg = False |
174 |
| - is_variable_layers = True |
175 |
| - self.use_slate_for_inverse = (use_slate_for_inverse and is_dg and not is_variable_layers |
176 |
| - and (not complex_mode or SLATE_SUPPORTS_COMPLEX)) |
| 166 | + |
| 167 | + F = self.target.function_space() |
| 168 | + if type(F.ufl_element()) is finat.ufl.MixedElement: |
| 169 | + slate_supported = False |
| 170 | + needs_trace = False |
| 171 | + else: |
| 172 | + slate_supported = (F.finat_element.is_dg() and not F.mesh().variable_layers |
| 173 | + and (not complex_mode or SLATE_SUPPORTS_COMPLEX)) |
| 174 | + needs_trace = F.ufl_element().family() in {"HDiv Trace", "Boundary Quadrature"} |
| 175 | + |
| 176 | + self.use_slate_for_inverse = use_slate_for_inverse and slate_supported |
| 177 | + self.needs_trace = needs_trace |
177 | 178 |
|
178 | 179 | @cached_property
|
179 | 180 | def A(self):
|
180 |
| - u = firedrake.TrialFunction(self.target.function_space()) |
181 |
| - v = firedrake.TestFunction(self.target.function_space()) |
182 | 181 | F = self.target.function_space()
|
183 |
| - mixed = isinstance(F.ufl_element(), finat.ufl.MixedElement) |
184 |
| - if not mixed and isinstance(F.finat_element, HDivTrace): |
| 182 | + u = firedrake.TrialFunction(F) |
| 183 | + v = firedrake.TestFunction(F) |
| 184 | + if self.needs_trace: |
185 | 185 | if F.extruded:
|
186 | 186 | a = (
|
187 | 187 | firedrake.inner(u, v)*firedrake.ds_t
|
@@ -247,12 +247,11 @@ class BasicProjector(ProjectorBase):
|
247 | 247 | def rhs_form(self):
|
248 | 248 | v = firedrake.TestFunction(self.target.function_space())
|
249 | 249 | F = self.target.function_space()
|
250 |
| - mixed = isinstance(F.ufl_element(), finat.ufl.MixedElement) |
251 |
| - if not mixed and isinstance(F.finat_element, HDivTrace): |
| 250 | + if self.needs_trace: |
252 | 251 | # Project onto a trace space by supplying the respective form on the facets.
|
253 | 252 | # The measures on the facets differ between extruded and non-extruded mesh.
|
254 | 253 | # FIXME The restrictions of cg onto the facets is also a trace space,
|
255 |
| - # but we only cover DGT. |
| 254 | + # but we only cover DGT and BQ. |
256 | 255 | if F.extruded:
|
257 | 256 | form = (
|
258 | 257 | firedrake.inner(self.source, v)*firedrake.ds_t
|
|
0 commit comments