diff --git a/psydac/api/ast/parser.py b/psydac/api/ast/parser.py index 97587fced..5602ded90 100644 --- a/psydac/api/ast/parser.py +++ b/psydac/api/ast/parser.py @@ -73,7 +73,7 @@ from .nodes import Zeros, ZerosLike, Array from .fem import expand, expand_hdiv_hcurl -from psydac.api.ast.utilities import variables, math_atoms_as_str +from psydac.api.ast.utilities import variables, math_atoms_as_str, get_name from psydac.api.utilities import flatten from psydac.api.ast.utilities import build_pythran_types_header from psydac.api.ast.utilities import build_pyccel_types_decorator @@ -1233,7 +1233,7 @@ def _visit_ComputeKernelExpr(self, expr, op=None, lhs=None, **kwargs): lhs = lhs[:] # Create a new name for the temporaries used in each patch - name=lhs[0]._name[12:-8] + name = get_name(lhs) temps, rhs = cse_main.cse(rhs, symbols=cse_main.numbered_symbols(prefix=f'temp{name}')) normal_vec_stmts = [] diff --git a/psydac/api/ast/utilities.py b/psydac/api/ast/utilities.py index 05bdf5294..00a11ea1d 100644 --- a/psydac/api/ast/utilities.py +++ b/psydac/api/ast/utilities.py @@ -1040,3 +1040,28 @@ def math_atoms_as_str(expr, lib='math'): sqrt = True return set.union(math_functions, math_constants) + +def get_name(lhs): + """ + Given a list of variable return the meaningful part of the name of the + first variable that has a _name attribute. + + Was added to solve issue #327 caused by trying to access the name of a + variable that has not such attribute. + + Parameters + ---------- + lhs : list + list from whom we need to extract a name. + + Returns + ------- + str + meaningful part of the name of the variable or "zero term" if no + variable has a name. + + """ + for term in lhs: + if hasattr(term, '_name'): + return term._name[12:-8] + return "zero_term" diff --git a/psydac/api/tests/test_assembly.py b/psydac/api/tests/test_assembly.py index 9a87516a8..0dfae99f5 100644 --- a/psydac/api/tests/test_assembly.py +++ b/psydac/api/tests/test_assembly.py @@ -10,6 +10,7 @@ from sympde.core import Constant from sympde.expr import LinearForm, BilinearForm, Functional, Norm from sympde.expr import integral +from sympde.calculus import Inner from psydac.linalg.solvers import inverse from psydac.api.discretization import discretize @@ -443,6 +444,32 @@ def test_non_symmetric_BilinearForm(backend): print("PASSED") +#============================================================================== +def test_non_symmetric_different_space_BilinearForm(backend): + + kwargs = {'backend': PSYDAC_BACKENDS[backend]} if backend else {} + + domain = Square() + V = VectorFunctionSpace('V', domain, kind='Hdiv') + X = VectorFunctionSpace('X', domain, kind='h1') + + u = element_of(X, name='u') + w = element_of(V, name='w') + + A = BilinearForm((u, w), integral(domain, Inner(u, w))) + + ncells = [4, 4] + degree = [2, 2] + + domain_h = discretize(domain, ncells=ncells) + Vh = discretize(V, domain_h, degree=degree) + Xh = discretize(X, domain_h, degree=degree) + + ah = discretize(A, domain_h, (Xh, Vh), **kwargs) + A = ah.assemble() + + print("PASSED") + #============================================================================== def test_assembly_no_synchr_args(backend): @@ -509,4 +536,5 @@ def test_assembly_no_synchr_args(backend): test_multiple_fields(None) test_math_imports(None) test_non_symmetric_BilinearForm(None) + test_non_symmetric_different_space_BilinearForm(None) test_assembly_no_synchr_args(None)