Actually, testing my variational form when the functionspace is a MixedFunctionSpace
type, this assertion I’ve made about the cross product causing the error is incorrect. In case I haven’t said this, the error comes at the step of reading the variational form into some PETSc’s KSP solver or dolfinx.fem.petsc.LinearProblem
when working with a mixed problem, however it appears as thought the cross product being involved (or ufl.perp(u)
in the 2D case) has nothing to do with it. Here is a shortened version (no projection included, and instead opting to interpolate despite not yielding correct results) on a square where the variational form is that of the Shallow Water Equations with all constants set to 1
\frac{\partial \textbf{u}}{\partial t} + f (\hat{\textbf{k}}\times\textbf{u}) + \nabla D = 0
\frac{\partial D}{\partial t} + \nabla \cdot \textbf{u} = 0
<\boldsymbol{w},\textbf{u}_t> + <\boldsymbol{w} ,f (\hat{\textbf{k}}\times\textbf{u})>-<\nabla \cdot \boldsymbol w, D> + <\phi,D_t> + <\nabla \cdot \textbf{u}>=0
from mpi4py import MPI
import numpy as np
from dolfinx import fem, mesh
from Projector import Projector
import ufl
def initial_conditions(S, V):
u0 = fem.Function(S)
u0.interpolate(lambda x: np.zeros(x[:S.mesh.topology.dim].shape))
D0 = fem.Function(V)
D0.interpolate(lambda x: np.exp(-((-x[1]-1)/0.1)**2))
return (u0, D0)
domain = mesh.create_unit_square(MPI.COMM_WORLD, 32, 32, mesh.CellType.quadrilateral)
x = ufl.SpatialCoordinate(domain)
S = fem.functionspace(domain, ("RT",1))
V = fem.functionspace(domain, ("DG",1))
W = ufl.MixedFunctionSpace(*(S, V))
# Initial values of solutions u and D
u_, D_ = initial_conditions(S, V)
(u, D) = ufl.TrialFunctions(W)
(w, phi) = ufl.TestFunctions(W)
# u_n = k x u
u_n = ufl.perp(u)
dt = 0.05 # delta t
f = x[1]# coriolis parameter
F = (
ufl.inner(u - u_, w)
- ufl.div(w) * D
+ dt * f * ufl.inner(u_n, w)
+ ufl.inner(D - D_, phi)
+ dt * ufl.div(u) * phi
) * ufl.dx
(a, L) = ufl.system(F)
petsc_options = {
"ksp_type": "preonly",
"pc_type": "lu",
"pc_factor_mat_solver_type": "mumps",
"ksp_error_if_not_converged": True,
}
problem = fem.petsc.LinearProblem(
a,
L,
bcs=[],
petsc_options=petsc_options,
petsc_options_prefix="mixed_poisson_",
kind="mpi",
)
returns the error:
---------------------------------------------------------------------------
ArityMismatch Traceback (most recent call last)
Cell In[13], line 7
1 petsc_options = {
2 "ksp_type": "preonly",
3 "pc_type": "lu",
4 "pc_factor_mat_solver_type": "mumps",
5 "ksp_error_if_not_converged": True,
6 }
----> 7 problem = fem.petsc.LinearProblem(
8 ufl.extract_blocks(a),
9 L,
10 bcs=[],
11 petsc_options=petsc_options,
12 petsc_options_prefix="mixed_poisson_",
13 kind="mpi",
14 )
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/fem/petsc.py:829, in LinearProblem.__init__(self, a, L, petsc_options_prefix, bcs, u, P, kind, petsc_options, form_compiler_options, jit_options, entity_maps)
743 """Initialize solver for a linear variational problem.
744
745 By default, the underlying KSP solver uses PETSc's default
(...) 820 entity ``i`` in the integration domain mesh.
821 """
822 self._a = _create_form(
823 a,
824 dtype=PETSc.ScalarType, # type: ignore[attr-defined]
(...) 827 entity_maps=entity_maps,
828 )
--> 829 self._L = _create_form(
830 L,
831 dtype=PETSc.ScalarType, # type: ignore[attr-defined]
832 form_compiler_options=form_compiler_options,
833 jit_options=jit_options,
834 entity_maps=entity_maps,
835 )
836 self._A = create_matrix(self._a, kind=kind)
837 self._preconditioner = _create_form(
838 P, # type: ignore[arg-type]
839 dtype=PETSc.ScalarType, # type: ignore[attr-defined]
(...) 842 entity_maps=entity_maps,
843 )
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/fem/forms.py:438, in form(form, dtype, form_compiler_options, jit_options, entity_maps)
435 else:
436 return form
--> 438 return _create_form(form)
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/fem/forms.py:430, in form.<locals>._create_form(form)
420 """Recursively convert ufl.Forms to dolfinx.fem.Form.
421
422 Args:
(...) 427 A ``dolfinx.fem.Form`` or a list of ``dolfinx.fem.Form``.
428 """
429 if isinstance(form, ufl.Form):
--> 430 return _form(form)
431 elif isinstance(form, ufl.ZeroBaseForm):
432 return _zero_form(form)
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/fem/forms.py:339, in form.<locals>._form(form)
337 if msh is None:
338 raise RuntimeError("Expecting to find a Mesh in the form.")
--> 339 ufcx_form, module, code = jit.ffcx_jit(
340 msh.comm, form, form_compiler_options=form_compiler_options, jit_options=jit_options
341 )
343 # For each argument in form extract its function space
344 V = [arg.ufl_function_space()._cpp_object for arg in form.arguments()]
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/jit.py:61, in mpi_jit_decorator.<locals>.mpi_jit(comm, *args, **kwargs)
57 @functools.wraps(local_jit)
58 def mpi_jit(comm, *args, **kwargs):
59 # Just call JIT compiler when running in serial
60 if comm.size == 1:
---> 61 return local_jit(*args, **kwargs)
63 # Default status (0 == ok, 1 == fail)
64 status = 0
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/jit.py:216, in ffcx_jit(ufl_object, form_compiler_options, jit_options)
214 # Switch on type and compile, returning cffi object
215 if isinstance(ufl_object, ufl.Form):
--> 216 r = ffcx.codegeneration.jit.compile_forms([ufl_object], options=p_ffcx, **p_jit)
217 elif isinstance(ufl_object, tuple) and isinstance(ufl_object[0], ufl.core.expr.Expr):
218 r = ffcx.codegeneration.jit.compile_expressions([ufl_object], options=p_ffcx, **p_jit)
File /dolfinx-env/lib/python3.12/site-packages/ffcx/codegeneration/jit.py:206, in compile_forms(forms, options, cache_dir, timeout, cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries, visualise)
203 for name in form_names:
204 decl += form_template.format(name=name)
--> 206 impl = _compile_objects(
207 decl,
208 forms,
209 form_names,
210 module_name,
211 p,
212 cache_dir,
213 cffi_extra_compile_args,
214 cffi_verbose,
215 cffi_debug,
216 cffi_libraries,
217 visualise=visualise,
218 )
219 except Exception as e:
220 try:
221 # remove c file so that it will not timeout next time
File /dolfinx-env/lib/python3.12/site-packages/ffcx/codegeneration/jit.py:331, in _compile_objects(decl, ufl_objects, object_names, module_name, options, cache_dir, cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries, visualise)
327 libraries = _libraries + cffi_libraries if cffi_libraries is not None else _libraries
329 # JIT uses module_name as prefix, which is needed to make names of all struct/function
330 # unique across modules
--> 331 _, code_body = ffcx.compiler.compile_ufl_objects(
332 ufl_objects, prefix=module_name, options=options, visualise=visualise
333 )
335 # Raise error immediately prior to compilation if no support for C99
336 # _Complex. Doing this here allows FFCx to be used for complex codegen on
337 # Windows.
338 if sys.platform.startswith("win32"):
File /dolfinx-env/lib/python3.12/site-packages/ffcx/compiler.py:108, in compile_ufl_objects(ufl_objects, options, object_names, prefix, visualise)
106 # Stage 1: analysis
107 cpu_time = time()
--> 108 analysis = analyze_ufl_objects(ufl_objects, options["scalar_type"]) # type: ignore
109 _print_timing(1, time() - cpu_time)
111 # Stage 2: intermediate representation
File /dolfinx-env/lib/python3.12/site-packages/ffcx/analysis.py:96, in analyze_ufl_objects(ufl_objects, scalar_type)
93 else:
94 raise TypeError("UFL objects not recognised.")
---> 96 form_data = tuple(_analyze_form(form, scalar_type) for form in forms)
97 for data in form_data:
98 elements += data.unique_sub_elements
File /dolfinx-env/lib/python3.12/site-packages/ffcx/analysis.py:96, in <genexpr>(.0)
93 else:
94 raise TypeError("UFL objects not recognised.")
---> 96 form_data = tuple(_analyze_form(form, scalar_type) for form in forms)
97 for data in form_data:
98 elements += data.unique_sub_elements
File /dolfinx-env/lib/python3.12/site-packages/ffcx/analysis.py:182, in _analyze_form(form, scalar_type)
179 complex_mode = np.issubdtype(scalar_type, np.complexfloating)
181 # Compute form metadata
--> 182 form_data: ufl.algorithms.formdata.FormData = ufl.algorithms.compute_form_data(
183 form,
184 do_apply_function_pullbacks=True,
185 do_apply_integral_scaling=True,
186 do_apply_geometry_lowering=True,
187 preserve_geometry_types=(ufl.classes.Jacobian,),
188 do_apply_restrictions=True,
189 do_append_everywhere_integrals=False, # do not add dx integrals to dx(i) in UFL
190 complex_mode=complex_mode,
191 )
193 # Determine unique quadrature degree and quadrature scheme
194 # per each integral data
195 for id, integral_data in enumerate(form_data.integral_data):
196 # Iterate through groups of integral data. There is one integral
197 # data for all integrals with same domain, itype, subdomain_id
(...) 201 # all integrals in this integral data group, i.e. must be the
202 # same for for the same (domain, itype, subdomain_id)
File /dolfinx-env/lib/python3.12/site-packages/ufl/algorithms/compute_form_data.py:482, in compute_form_data(form, do_apply_function_pullbacks, do_apply_integral_scaling, do_apply_geometry_lowering, preserve_geometry_types, do_apply_default_restrictions, do_apply_restrictions, do_estimate_degrees, do_append_everywhere_integrals, do_replace_functions, coefficients_to_split, complex_mode, do_remove_component_tensors)
479 preprocessed_form = reconstruct_form_from_integral_data(self.integral_data)
481 # TODO: Test how fast this is
--> 482 check_form_arity(preprocessed_form, self.original_form.arguments(), complex_mode)
484 # TODO: This member is used by unit tests, change the tests to
485 # remove this!
486 self.preprocessed_form = preprocessed_form
File /dolfinx-env/lib/python3.12/site-packages/ufl/algorithms/check_arities.py:213, in check_form_arity(form, arguments, complex_mode)
211 """Check the arity of a form."""
212 for itg in form.integrals():
--> 213 check_integrand_arity(itg.integrand(), arguments, complex_mode)
File /dolfinx-env/lib/python3.12/site-packages/ufl/algorithms/check_arities.py:194, in check_integrand_arity(expr, arguments, complex_mode)
192 arguments = tuple(sorted(set(arguments), key=lambda x: (x.number(), x.part())))
193 rules = ArityChecker(arguments)
--> 194 arg_tuples = map_expr_dag(rules, expr, compress=False)
195 args = tuple(a[0] for a in arg_tuples)
196 if args != arguments:
File /dolfinx-env/lib/python3.12/site-packages/ufl/corealg/map_dag.py:35, in map_expr_dag(function, expression, compress, vcache, rcache)
15 def map_expr_dag(function, expression, compress=True, vcache=None, rcache=None):
16 """Apply a function to each subexpression node in an expression DAG.
17
18 If the same function is called multiple times in a transformation
(...) 33 The result of the final function call
34 """
---> 35 (result,) = map_expr_dags(
36 function, [expression], compress=compress, vcache=vcache, rcache=rcache
37 )
38 return result
File /dolfinx-env/lib/python3.12/site-packages/ufl/corealg/map_dag.py:103, in map_expr_dags(function, expressions, compress, vcache, rcache)
101 r = handlers[v._ufl_typecode_](v)
102 else:
--> 103 r = handlers[v._ufl_typecode_](v, *(vcache[u] for u in v.ufl_operands))
105 # Optionally check if r is in rcache, a memory optimization
106 # to be able to keep representation of result compact
107 if compress:
File /dolfinx-env/lib/python3.12/site-packages/ufl/algorithms/check_arities.py:58, in ArityChecker.sum(self, o, a, b)
56 """Apply to sum."""
57 if a != b:
---> 58 raise ArityMismatch(
59 f"Adding expressions with non-matching form arguments "
60 f"{tuple(map(_afmt, a))} vs {tuple(map(_afmt, b))}."
61 )
62 return a
ArityMismatch: Adding expressions with non-matching form arguments ('v_0^1',) vs ('v_0^0',).
If we use the special case where f=0, and therefore no cross product is present, by replacing the last lines with
F = (
ufl.inner(u - u_, w)
- ufl.div(w) * D
+ ufl.inner(D - D_, phi)
+ dt * ufl.div(u) * phi
) * ufl.dx
(a, L) = ufl.system(F)
petsc_options = {
"ksp_type": "preonly",
"pc_type": "lu",
"pc_factor_mat_solver_type": "mumps",
"ksp_error_if_not_converged": True,
}
problem = fem.petsc.LinearProblem(
a,
L,
bcs=[],
petsc_options=petsc_options,
petsc_options_prefix="mixed_poisson_",
kind="mpi",
)
I get similar error as before
---------------------------------------------------------------------------
ArityMismatch Traceback (most recent call last)
Cell In[1], line 47
39 (a, L) = ufl.system(F)
41 petsc_options = {
42 "ksp_type": "preonly",
43 "pc_type": "lu",
44 "pc_factor_mat_solver_type": "mumps",
45 "ksp_error_if_not_converged": True,
46 }
---> 47 problem = fem.petsc.LinearProblem(
48 a,
49 L,
50 bcs=[],
51 petsc_options=petsc_options,
52 petsc_options_prefix="mixed_poisson_",
53 kind="mpi",
54 )
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/fem/petsc.py:822, in LinearProblem.__init__(self, a, L, petsc_options_prefix, bcs, u, P, kind, petsc_options, form_compiler_options, jit_options, entity_maps)
728 def __init__(
729 self,
730 a: typing.Union[ufl.Form, Sequence[Sequence[ufl.Form]]],
(...) 741 entity_maps: typing.Optional[Sequence[_EntityMap]] = None,
742 ) -> None:
743 """Initialize solver for a linear variational problem.
744
745 By default, the underlying KSP solver uses PETSc's default
(...) 820 entity ``i`` in the integration domain mesh.
821 """
--> 822 self._a = _create_form(
823 a,
824 dtype=PETSc.ScalarType, # type: ignore[attr-defined]
825 form_compiler_options=form_compiler_options,
826 jit_options=jit_options,
827 entity_maps=entity_maps,
828 )
829 self._L = _create_form(
830 L,
831 dtype=PETSc.ScalarType, # type: ignore[attr-defined]
(...) 834 entity_maps=entity_maps,
835 )
836 self._A = create_matrix(self._a, kind=kind)
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/fem/forms.py:438, in form(form, dtype, form_compiler_options, jit_options, entity_maps)
435 else:
436 return form
--> 438 return _create_form(form)
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/fem/forms.py:430, in form.<locals>._create_form(form)
420 """Recursively convert ufl.Forms to dolfinx.fem.Form.
421
422 Args:
(...) 427 A ``dolfinx.fem.Form`` or a list of ``dolfinx.fem.Form``.
428 """
429 if isinstance(form, ufl.Form):
--> 430 return _form(form)
431 elif isinstance(form, ufl.ZeroBaseForm):
432 return _zero_form(form)
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/fem/forms.py:339, in form.<locals>._form(form)
337 if msh is None:
338 raise RuntimeError("Expecting to find a Mesh in the form.")
--> 339 ufcx_form, module, code = jit.ffcx_jit(
340 msh.comm, form, form_compiler_options=form_compiler_options, jit_options=jit_options
341 )
343 # For each argument in form extract its function space
344 V = [arg.ufl_function_space()._cpp_object for arg in form.arguments()]
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/jit.py:61, in mpi_jit_decorator.<locals>.mpi_jit(comm, *args, **kwargs)
57 @functools.wraps(local_jit)
58 def mpi_jit(comm, *args, **kwargs):
59 # Just call JIT compiler when running in serial
60 if comm.size == 1:
---> 61 return local_jit(*args, **kwargs)
63 # Default status (0 == ok, 1 == fail)
64 status = 0
File /usr/local/dolfinx-real/lib/python3.12/dist-packages/dolfinx/jit.py:216, in ffcx_jit(ufl_object, form_compiler_options, jit_options)
214 # Switch on type and compile, returning cffi object
215 if isinstance(ufl_object, ufl.Form):
--> 216 r = ffcx.codegeneration.jit.compile_forms([ufl_object], options=p_ffcx, **p_jit)
217 elif isinstance(ufl_object, tuple) and isinstance(ufl_object[0], ufl.core.expr.Expr):
218 r = ffcx.codegeneration.jit.compile_expressions([ufl_object], options=p_ffcx, **p_jit)
File /dolfinx-env/lib/python3.12/site-packages/ffcx/codegeneration/jit.py:206, in compile_forms(forms, options, cache_dir, timeout, cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries, visualise)
203 for name in form_names:
204 decl += form_template.format(name=name)
--> 206 impl = _compile_objects(
207 decl,
208 forms,
209 form_names,
210 module_name,
211 p,
212 cache_dir,
213 cffi_extra_compile_args,
214 cffi_verbose,
215 cffi_debug,
216 cffi_libraries,
217 visualise=visualise,
218 )
219 except Exception as e:
220 try:
221 # remove c file so that it will not timeout next time
File /dolfinx-env/lib/python3.12/site-packages/ffcx/codegeneration/jit.py:331, in _compile_objects(decl, ufl_objects, object_names, module_name, options, cache_dir, cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries, visualise)
327 libraries = _libraries + cffi_libraries if cffi_libraries is not None else _libraries
329 # JIT uses module_name as prefix, which is needed to make names of all struct/function
330 # unique across modules
--> 331 _, code_body = ffcx.compiler.compile_ufl_objects(
332 ufl_objects, prefix=module_name, options=options, visualise=visualise
333 )
335 # Raise error immediately prior to compilation if no support for C99
336 # _Complex. Doing this here allows FFCx to be used for complex codegen on
337 # Windows.
338 if sys.platform.startswith("win32"):
File /dolfinx-env/lib/python3.12/site-packages/ffcx/compiler.py:108, in compile_ufl_objects(ufl_objects, options, object_names, prefix, visualise)
106 # Stage 1: analysis
107 cpu_time = time()
--> 108 analysis = analyze_ufl_objects(ufl_objects, options["scalar_type"]) # type: ignore
109 _print_timing(1, time() - cpu_time)
111 # Stage 2: intermediate representation
File /dolfinx-env/lib/python3.12/site-packages/ffcx/analysis.py:96, in analyze_ufl_objects(ufl_objects, scalar_type)
93 else:
94 raise TypeError("UFL objects not recognised.")
---> 96 form_data = tuple(_analyze_form(form, scalar_type) for form in forms)
97 for data in form_data:
98 elements += data.unique_sub_elements
File /dolfinx-env/lib/python3.12/site-packages/ffcx/analysis.py:96, in <genexpr>(.0)
93 else:
94 raise TypeError("UFL objects not recognised.")
---> 96 form_data = tuple(_analyze_form(form, scalar_type) for form in forms)
97 for data in form_data:
98 elements += data.unique_sub_elements
File /dolfinx-env/lib/python3.12/site-packages/ffcx/analysis.py:182, in _analyze_form(form, scalar_type)
179 complex_mode = np.issubdtype(scalar_type, np.complexfloating)
181 # Compute form metadata
--> 182 form_data: ufl.algorithms.formdata.FormData = ufl.algorithms.compute_form_data(
183 form,
184 do_apply_function_pullbacks=True,
185 do_apply_integral_scaling=True,
186 do_apply_geometry_lowering=True,
187 preserve_geometry_types=(ufl.classes.Jacobian,),
188 do_apply_restrictions=True,
189 do_append_everywhere_integrals=False, # do not add dx integrals to dx(i) in UFL
190 complex_mode=complex_mode,
191 )
193 # Determine unique quadrature degree and quadrature scheme
194 # per each integral data
195 for id, integral_data in enumerate(form_data.integral_data):
196 # Iterate through groups of integral data. There is one integral
197 # data for all integrals with same domain, itype, subdomain_id
(...) 201 # all integrals in this integral data group, i.e. must be the
202 # same for for the same (domain, itype, subdomain_id)
File /dolfinx-env/lib/python3.12/site-packages/ufl/algorithms/compute_form_data.py:482, in compute_form_data(form, do_apply_function_pullbacks, do_apply_integral_scaling, do_apply_geometry_lowering, preserve_geometry_types, do_apply_default_restrictions, do_apply_restrictions, do_estimate_degrees, do_append_everywhere_integrals, do_replace_functions, coefficients_to_split, complex_mode, do_remove_component_tensors)
479 preprocessed_form = reconstruct_form_from_integral_data(self.integral_data)
481 # TODO: Test how fast this is
--> 482 check_form_arity(preprocessed_form, self.original_form.arguments(), complex_mode)
484 # TODO: This member is used by unit tests, change the tests to
485 # remove this!
486 self.preprocessed_form = preprocessed_form
File /dolfinx-env/lib/python3.12/site-packages/ufl/algorithms/check_arities.py:213, in check_form_arity(form, arguments, complex_mode)
211 """Check the arity of a form."""
212 for itg in form.integrals():
--> 213 check_integrand_arity(itg.integrand(), arguments, complex_mode)
File /dolfinx-env/lib/python3.12/site-packages/ufl/algorithms/check_arities.py:194, in check_integrand_arity(expr, arguments, complex_mode)
192 arguments = tuple(sorted(set(arguments), key=lambda x: (x.number(), x.part())))
193 rules = ArityChecker(arguments)
--> 194 arg_tuples = map_expr_dag(rules, expr, compress=False)
195 args = tuple(a[0] for a in arg_tuples)
196 if args != arguments:
File /dolfinx-env/lib/python3.12/site-packages/ufl/corealg/map_dag.py:35, in map_expr_dag(function, expression, compress, vcache, rcache)
15 def map_expr_dag(function, expression, compress=True, vcache=None, rcache=None):
16 """Apply a function to each subexpression node in an expression DAG.
17
18 If the same function is called multiple times in a transformation
(...) 33 The result of the final function call
34 """
---> 35 (result,) = map_expr_dags(
36 function, [expression], compress=compress, vcache=vcache, rcache=rcache
37 )
38 return result
File /dolfinx-env/lib/python3.12/site-packages/ufl/corealg/map_dag.py:103, in map_expr_dags(function, expressions, compress, vcache, rcache)
101 r = handlers[v._ufl_typecode_](v)
102 else:
--> 103 r = handlers[v._ufl_typecode_](v, *(vcache[u] for u in v.ufl_operands))
105 # Optionally check if r is in rcache, a memory optimization
106 # to be able to keep representation of result compact
107 if compress:
File /dolfinx-env/lib/python3.12/site-packages/ufl/algorithms/check_arities.py:58, in ArityChecker.sum(self, o, a, b)
56 """Apply to sum."""
57 if a != b:
---> 58 raise ArityMismatch(
59 f"Adding expressions with non-matching form arguments "
60 f"{tuple(map(_afmt, a))} vs {tuple(map(_afmt, b))}."
61 )
62 return a
ArityMismatch: Adding expressions with non-matching form arguments ('v_0^0', 'v_1^1') vs ('v_0^1', 'v_1^1').
. The errors go away when replacing the lines creating the functionspaces with
S_el = basix.ufl.element("RT", domain.basix_cell(), 1)
S = fem.functionspace(domain, S_el)
V_el = basix.ufl.element("DG", domain.basix_cell(), 0)
V = fem.functionspace(domain, V_el)
W_el = basix.ufl.mixed_element([S_el, V_el])
W = fem.functionspace(domain, W_el)
This might help clear some things up:
I originally tried to follow your example here as a template for handling this time varying problem as they both use a similar mixed function space, however examining it again, I just am now noticing some differences in your variational form from the one I tried to set up (which might hold the answer for this “non-matching form” error).
a = (
ufl.inner(sigma_, tau_) + ufl.div(sigma_) * v + ufl.div(tau_) * u + r * v + t * u
) * ufl.dx
L = [ufl.ZeroBaseForm((tau,)), g * v * ufl.dx, ufl.ZeroBaseForm((t,))]
Your L is a list of 3 items rather than simply a convolution of the RHS, g
, and the test function, v
. Your list instead, contains that integral as well as the other 2 test functions by themselves, being the tau vector and t scalar; I don’t know what ZeroBaseForm
means or what it does. Is my Linear term on the RHS supposed to be like it is here; does it have anything to do with the error about mismatching forms?