File: test_add_mode.py

package info (click to toggle)
fenics-ffcx 1%3A0.5.0-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 964 kB
  • sloc: python: 7,534; ansic: 194; makefile: 58
file content (117 lines) | stat: -rw-r--r-- 4,389 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# Copyright (C) 2019 Chris Richardson
#
# This file is part of FFCx. (https://www.fenicsproject.org)
#
# SPDX-License-Identifier:    LGPL-3.0-or-later

import ffcx.codegeneration.jit
import numpy as np
import pytest
import ufl
from ffcx.naming import cdtype_to_numpy, scalar_to_value_type


@pytest.mark.parametrize("mode",
                         [
                             "double",
                             "float",
                             "long double",
                             "double _Complex",
                             "float _Complex"
                         ])
def test_additive_facet_integral(mode, compile_args):
    cell = ufl.triangle
    element = ufl.FiniteElement("Lagrange", cell, 1)
    u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
    a = ufl.inner(u, v) * ufl.ds
    forms = [a]
    compiled_forms, module, code = ffcx.codegeneration.jit.compile_forms(
        forms, parameters={'scalar_type': mode}, cffi_extra_compile_args=compile_args)

    for f, compiled_f in zip(forms, compiled_forms):
        assert compiled_f.rank == len(f.arguments())

    ffi = module.ffi
    form0 = compiled_forms[0]

    assert form0.num_integrals(module.lib.exterior_facet) == 1
    ids = form0.integral_ids(module.lib.exterior_facet)
    assert ids[0] == -1

    default_integral = form0.integrals(module.lib.exterior_facet)[0]

    np_type = cdtype_to_numpy(mode)
    A = np.zeros((3, 3), dtype=np_type)
    w = np.array([], dtype=np_type)
    c = np.array([], dtype=np_type)
    facets = np.array([0], dtype=np.int32)
    perm = np.array([0], dtype=np.uint8)

    geom_type = scalar_to_value_type(mode)
    np_gtype = cdtype_to_numpy(geom_type)
    coords = np.array([0.0, 2.0, 0.0,
                       np.sqrt(3.0), -1.0, 0.0,
                       -np.sqrt(3.0), -1.0, 0.0], dtype=np_gtype)

    kernel = getattr(default_integral, f"tabulate_tensor_{np_type}")

    for i in range(3):
        facets[0] = i
        kernel(ffi.cast('{type} *'.format(type=mode), A.ctypes.data),
               ffi.cast('{type} *'.format(type=mode), w.ctypes.data),
               ffi.cast('{type} *'.format(type=mode), c.ctypes.data),
               ffi.cast(f'{geom_type} *', coords.ctypes.data),
               ffi.cast('int *', facets.ctypes.data),
               ffi.cast('uint8_t *', perm.ctypes.data))

        assert np.isclose(A.sum(), np.sqrt(12) * (i + 1))


@pytest.mark.parametrize("mode", ["double", "float", "long double", "double _Complex", "float _Complex"])
def test_additive_cell_integral(mode, compile_args):
    cell = ufl.triangle
    element = ufl.FiniteElement("Lagrange", cell, 1)
    u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
    a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
    forms = [a]
    compiled_forms, module, code = ffcx.codegeneration.jit.compile_forms(
        forms, parameters={'scalar_type': mode}, cffi_extra_compile_args=compile_args)

    for f, compiled_f in zip(forms, compiled_forms):
        assert compiled_f.rank == len(f.arguments())

    ffi = module.ffi
    form0 = compiled_forms[0]

    assert form0.num_integrals(module.lib.cell) == 1
    ids = form0.integral_ids(module.lib.cell)
    assert ids[0] == -1

    default_integral = form0.integrals(0)[0]

    np_type = cdtype_to_numpy(mode)
    A = np.zeros((3, 3), dtype=np_type)
    w = np.array([], dtype=np_type)
    c = np.array([], dtype=np_type)

    geom_type = scalar_to_value_type(mode)
    np_gtype = cdtype_to_numpy(geom_type)
    coords = np.array([0.0, 2.0, 0.0,
                       np.sqrt(3.0), -1.0, 0.0,
                       -np.sqrt(3.0), -1.0, 0.0], dtype=np_gtype)

    kernel = getattr(default_integral, f"tabulate_tensor_{np_type}")

    kernel(ffi.cast('{type} *'.format(type=mode), A.ctypes.data),
           ffi.cast('{type} *'.format(type=mode), w.ctypes.data),
           ffi.cast('{type} *'.format(type=mode), c.ctypes.data),
           ffi.cast(f'{geom_type} *', coords.ctypes.data), ffi.NULL, ffi.NULL)

    A0 = np.array(A)
    for i in range(3):
        kernel(ffi.cast('{type} *'.format(type=mode), A.ctypes.data),
               ffi.cast('{type} *'.format(type=mode), w.ctypes.data),
               ffi.cast('{type} *'.format(type=mode), c.ctypes.data),
               ffi.cast(f'{geom_type} *', coords.ctypes.data), ffi.NULL, ffi.NULL)

        assert np.all(np.isclose(A, (i + 2) * A0))