|
1 | 1 | # -*- coding: utf-8 -*-
|
2 |
| -# Copyright (C) 2019-2022 Michal Habera and Jørgen S. Dokken |
| 2 | +# Copyright (C) 2019-2024 Michal Habera and Jørgen S. Dokken |
3 | 3 | #
|
4 | 4 | # This file is part of FFCx.(https://www.fenicsproject.org)
|
5 | 5 | #
|
6 | 6 | # SPDX-License-Identifier: LGPL-3.0-or-later
|
7 | 7 |
|
8 | 8 | import cffi
|
9 | 9 | import numpy as np
|
| 10 | +import pytest |
10 | 11 |
|
11 | 12 | import basix
|
12 | 13 | import basix.ufl
|
@@ -208,3 +209,45 @@ def exact_expr(x):
|
208 | 209 | exact = exact_expr(points.T)
|
209 | 210 |
|
210 | 211 | assert np.allclose(exact, output)
|
| 212 | + |
| 213 | + |
| 214 | +def test_grad_constant(compile_args): |
| 215 | + """Test if numbering of constants are correct after UFL eliminates the constant inside the gradient.""" |
| 216 | + c_el = basix.ufl.element("Lagrange", "triangle", 1, shape=(2, )) |
| 217 | + mesh = ufl.Mesh(c_el) |
| 218 | + |
| 219 | + x = ufl.SpatialCoordinate(mesh) |
| 220 | + first_constant = ufl.Constant(mesh) |
| 221 | + second_constant = ufl.Constant(mesh) |
| 222 | + expr = second_constant * ufl.Dx(x[0]**2 + first_constant, 0) |
| 223 | + |
| 224 | + dtype = np.float64 |
| 225 | + points = np.array([[0.33, 0.25]], dtype=dtype) |
| 226 | + |
| 227 | + obj, _, _ = ffcx.codegeneration.jit.compile_expressions( |
| 228 | + [(expr, points)], cffi_extra_compile_args=compile_args) |
| 229 | + |
| 230 | + ffi = cffi.FFI() |
| 231 | + expression = obj[0] |
| 232 | + |
| 233 | + c_type = "double" |
| 234 | + c_xtype = "double" |
| 235 | + |
| 236 | + output = np.zeros(1, dtype=dtype) |
| 237 | + |
| 238 | + # Define constants |
| 239 | + coords = np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], dtype=dtype) |
| 240 | + u_coeffs = np.array([], dtype=dtype) |
| 241 | + consts = np.array([3, 7], dtype=dtype) |
| 242 | + entity_index = np.array([0], dtype=np.intc) |
| 243 | + quad_perm = np.array([0], dtype=np.dtype("uint8")) |
| 244 | + |
| 245 | + expression.tabulate_tensor_float64( |
| 246 | + ffi.cast(f'{c_type} *', output.ctypes.data), |
| 247 | + ffi.cast(f'{c_type} *', u_coeffs.ctypes.data), |
| 248 | + ffi.cast(f'{c_type} *', consts.ctypes.data), |
| 249 | + ffi.cast(f'{c_xtype} *', coords.ctypes.data), |
| 250 | + ffi.cast('int *', entity_index.ctypes.data), |
| 251 | + ffi.cast('uint8_t *', quad_perm.ctypes.data)) |
| 252 | + |
| 253 | + assert output[0] == pytest.approx(consts[1] * 2 * points[0, 0]) |
0 commit comments