xref: /libCEED/python/ceed_qfunction.py (revision 3d8e882215d238700cdceb37404f76ca7fa24eaa)
1*3d8e8822SJeremy L Thompson# Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors
2*3d8e8822SJeremy L Thompson# All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3f8bc67e5Sjeremylt#
4*3d8e8822SJeremy L Thompson# SPDX-License-Identifier: BSD-2-Clause
5f8bc67e5Sjeremylt#
6*3d8e8822SJeremy L Thompson# This file is part of CEED:  http://github.com/ceed
7f8bc67e5Sjeremylt
8f8bc67e5Sjeremyltfrom _ceed_cffi import ffi, lib
9f8bc67e5Sjeremyltimport ctypes
10f8bc67e5Sjeremyltimport tempfile
11f8bc67e5Sjeremyltfrom abc import ABC
12f8bc67e5Sjeremylt
13f8bc67e5Sjeremylt# ------------------------------------------------------------------------------
147a7b0fa3SJed Brown
157a7b0fa3SJed Brown
16f8bc67e5Sjeremyltclass _QFunctionBase(ABC):
17f8bc67e5Sjeremylt    """Ceed QFunction: point-wise operation at quadrature points for evaluating
18f8bc67e5Sjeremylt         volumetric terms."""
19f8bc67e5Sjeremylt
20f8bc67e5Sjeremylt    # Destructor
21f8bc67e5Sjeremylt    def __del__(self):
22f8bc67e5Sjeremylt        # libCEED call
23477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionDestroy(self._pointer)
24477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
25f8bc67e5Sjeremylt
26f8bc67e5Sjeremylt    # Representation
27f8bc67e5Sjeremylt    def __repr__(self):
28f8bc67e5Sjeremylt        return "<CeedQFunction instance at " + hex(id(self)) + ">"
29f8bc67e5Sjeremylt
30f8bc67e5Sjeremylt    # String conversion for print() to stdout
31f8bc67e5Sjeremylt    def __str__(self):
32f8bc67e5Sjeremylt        """View a QFunction via print()."""
33f8bc67e5Sjeremylt
34f8bc67e5Sjeremylt        # libCEED call
35f8bc67e5Sjeremylt        with tempfile.NamedTemporaryFile() as key_file:
36f8bc67e5Sjeremylt            with open(key_file.name, 'r+') as stream_file:
37f8bc67e5Sjeremylt                stream = ffi.cast("FILE *", stream_file)
38f8bc67e5Sjeremylt
39477729cfSJeremy L Thompson                err_code = lib.CeedQFunctionView(self._pointer[0], stream)
40477729cfSJeremy L Thompson                self._ceed._check_error(err_code)
41f8bc67e5Sjeremylt
42f8bc67e5Sjeremylt                stream_file.seek(0)
43f8bc67e5Sjeremylt                out_string = stream_file.read()
44f8bc67e5Sjeremylt
45f8bc67e5Sjeremylt        return out_string
46f8bc67e5Sjeremylt
47f8bc67e5Sjeremylt    # Apply CeedQFunction
48f8bc67e5Sjeremylt    def apply(self, q, inputs, outputs):
49f8bc67e5Sjeremylt        """Apply the action of a QFunction.
50f8bc67e5Sjeremylt
51f8bc67e5Sjeremylt           Args:
52f8bc67e5Sjeremylt             q: number of quadrature points
53f8bc67e5Sjeremylt             *inputs: array of input data vectors
54f8bc67e5Sjeremylt             *outputs: array of output data vectors"""
55f8bc67e5Sjeremylt
56f8bc67e5Sjeremylt        # Array of vectors
57f8bc67e5Sjeremylt        invecs = ffi.new("CeedVector[16]")
58f8bc67e5Sjeremylt        for i in range(min(16, len(inputs))):
59f8bc67e5Sjeremylt            invecs[i] = inputs[i]._pointer[0]
60f8bc67e5Sjeremylt        outvecs = ffi.new("CeedVector[16]")
61f8bc67e5Sjeremylt        for i in range(min(16, len(outputs))):
62f8bc67e5Sjeremylt            outvecs[i] = outputs[i]._pointer[0]
63f8bc67e5Sjeremylt
64f8bc67e5Sjeremylt        # libCEED call
65477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionApply(self._pointer[0], q, invecs, outvecs)
66477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
67f8bc67e5Sjeremylt
68f8bc67e5Sjeremylt        # Clean-up
69f8bc67e5Sjeremylt        ffi.release(invecs)
70f8bc67e5Sjeremylt        ffi.release(outvecs)
71f8bc67e5Sjeremylt
72f8bc67e5Sjeremylt
73f8bc67e5Sjeremylt# ------------------------------------------------------------------------------
74f8bc67e5Sjeremyltclass QFunction(_QFunctionBase):
75f8bc67e5Sjeremylt    """Ceed QFunction: point-wise operation at quadrature points for evaluating
76f8bc67e5Sjeremylt         volumetric terms."""
77f8bc67e5Sjeremylt
78f8bc67e5Sjeremylt    # Constructor
79f8bc67e5Sjeremylt    def __init__(self, ceed, vlength, f, source):
80f8bc67e5Sjeremylt        # libCEED object
81f8bc67e5Sjeremylt        self._pointer = ffi.new("CeedQFunction *")
82f8bc67e5Sjeremylt
83f8bc67e5Sjeremylt        # Reference to Ceed
84f8bc67e5Sjeremylt        self._ceed = ceed
85f8bc67e5Sjeremylt
86f8bc67e5Sjeremylt        # Function pointer
877a7b0fa3SJed Brown        fpointer = ffi.cast(
887a7b0fa3SJed Brown            "CeedQFunctionUser", ctypes.cast(
897a7b0fa3SJed Brown                f, ctypes.c_void_p).value)
90f8bc67e5Sjeremylt
91f8bc67e5Sjeremylt        # libCEED call
92f8bc67e5Sjeremylt        sourceAscii = ffi.new("char[]", source.encode('ascii'))
93477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionCreateInterior(self._ceed._pointer[0], vlength,
94477729cfSJeremy L Thompson                                                   fpointer, sourceAscii, self._pointer)
95477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
96f8bc67e5Sjeremylt
97f8bc67e5Sjeremylt    # Set context data
98f8bc67e5Sjeremylt    def set_context(self, ctx):
99f8bc67e5Sjeremylt        """Set global context for a QFunction.
100f8bc67e5Sjeremylt
101f8bc67e5Sjeremylt           Args:
102777ff853SJeremy L Thompson             ctx: Ceed User Context object holding context data"""
103f8bc67e5Sjeremylt
104f8bc67e5Sjeremylt        # libCEED call
105477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionSetContext(
106777ff853SJeremy L Thompson            self._pointer[0],
107777ff853SJeremy L Thompson            ctx._pointer[0])
108477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
109f8bc67e5Sjeremylt
110f8bc67e5Sjeremylt    # Add fields to CeedQFunction
111f8bc67e5Sjeremylt    def add_input(self, fieldname, size, emode):
112f8bc67e5Sjeremylt        """Add a QFunction input.
113f8bc67e5Sjeremylt
114f8bc67e5Sjeremylt           Args:
115f8bc67e5Sjeremylt             fieldname: name of QFunction field
116f8bc67e5Sjeremylt             size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or
117f8bc67e5Sjeremylt                     (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP
118f8bc67e5Sjeremylt             **emode: CEED_EVAL_NONE to use values directly,
119f8bc67e5Sjeremylt                      CEED_EVAL_INTERP to use interpolated values,
120f8bc67e5Sjeremylt                      CEED_EVAL_GRAD to use gradients."""
121f8bc67e5Sjeremylt
122f8bc67e5Sjeremylt        # libCEED call
123f8bc67e5Sjeremylt        fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii'))
124477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionAddInput(
125450bb777Svaleriabarra            self._pointer[0], fieldnameAscii, size, emode)
126477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
127f8bc67e5Sjeremylt
128f8bc67e5Sjeremylt    def add_output(self, fieldname, size, emode):
129f8bc67e5Sjeremylt        """Add a QFunction output.
130f8bc67e5Sjeremylt
131f8bc67e5Sjeremylt           Args:
132f8bc67e5Sjeremylt             fieldname: name of QFunction field
133f8bc67e5Sjeremylt             size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or
134f8bc67e5Sjeremylt                     (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP
135f8bc67e5Sjeremylt             **emode: CEED_EVAL_NONE to use values directly,
136f8bc67e5Sjeremylt                      CEED_EVAL_INTERP to use interpolated values,
137f8bc67e5Sjeremylt                      CEED_EVAL_GRAD to use gradients."""
138f8bc67e5Sjeremylt
139f8bc67e5Sjeremylt        # libCEED call
140f8bc67e5Sjeremylt        fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii'))
141477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionAddOutput(
1427a7b0fa3SJed Brown            self._pointer[0], fieldnameAscii, size, emode)
143477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
144f8bc67e5Sjeremylt
145f8bc67e5Sjeremylt# ------------------------------------------------------------------------------
1467a7b0fa3SJed Brown
1477a7b0fa3SJed Brown
148f8bc67e5Sjeremyltclass QFunctionByName(_QFunctionBase):
149f8bc67e5Sjeremylt    """Ceed QFunction By Name: point-wise operation at quadrature points
150f8bc67e5Sjeremylt         from a given gallery, for evaluating volumetric terms."""
151f8bc67e5Sjeremylt
152f8bc67e5Sjeremylt    # Constructor
153f8bc67e5Sjeremylt    def __init__(self, ceed, name):
154f8bc67e5Sjeremylt        # libCEED object
155f8bc67e5Sjeremylt        self._pointer = ffi.new("CeedQFunction *")
156f8bc67e5Sjeremylt
157f8bc67e5Sjeremylt        # Reference to Ceed
158f8bc67e5Sjeremylt        self._ceed = ceed
159f8bc67e5Sjeremylt
160f8bc67e5Sjeremylt        # libCEED call
161f8bc67e5Sjeremylt        nameAscii = ffi.new("char[]", name.encode('ascii'))
162477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionCreateInteriorByName(self._ceed._pointer[0],
163477729cfSJeremy L Thompson                                                         nameAscii, self._pointer)
164477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
165f8bc67e5Sjeremylt
166f8bc67e5Sjeremylt# ------------------------------------------------------------------------------
1677a7b0fa3SJed Brown
1687a7b0fa3SJed Brown
169f8bc67e5Sjeremyltclass IdentityQFunction(_QFunctionBase):
170f8bc67e5Sjeremylt    """Ceed Identity QFunction: identity qfunction operation."""
171f8bc67e5Sjeremylt
172f8bc67e5Sjeremylt    # Constructor
173f8bc67e5Sjeremylt    def __init__(self, ceed, size, inmode, outmode):
174f8bc67e5Sjeremylt        # libCEED object
175f8bc67e5Sjeremylt        self._pointer = ffi.new("CeedQFunction *")
176f8bc67e5Sjeremylt
177f8bc67e5Sjeremylt        # Reference to Ceed
178f8bc67e5Sjeremylt        self._ceed = ceed
179f8bc67e5Sjeremylt
180f8bc67e5Sjeremylt        # libCEED call
181477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionCreateIdentity(self._ceed._pointer[0], size,
182477729cfSJeremy L Thompson                                                   inmode, outmode, self._pointer)
183f8bc67e5Sjeremylt
184f8bc67e5Sjeremylt# ------------------------------------------------------------------------------
185