xref: /libCEED/python/ceed_qfunction.py (revision 477729cfdbe3383ce841609affbc919aa37fc70d)
1f8bc67e5Sjeremylt# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2f8bc67e5Sjeremylt# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3f8bc67e5Sjeremylt# reserved. See files LICENSE and NOTICE for details.
4f8bc67e5Sjeremylt#
5f8bc67e5Sjeremylt# This file is part of CEED, a collection of benchmarks, miniapps, software
6f8bc67e5Sjeremylt# libraries and APIs for efficient high-order finite element and spectral
7f8bc67e5Sjeremylt# element discretizations for exascale applications. For more information and
8f8bc67e5Sjeremylt# source code availability see http://github.com/ceed.
9f8bc67e5Sjeremylt#
10f8bc67e5Sjeremylt# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11f8bc67e5Sjeremylt# a collaborative effort of two U.S. Department of Energy organizations (Office
12f8bc67e5Sjeremylt# of Science and the National Nuclear Security Administration) responsible for
13f8bc67e5Sjeremylt# the planning and preparation of a capable exascale ecosystem, including
14f8bc67e5Sjeremylt# software, applications, hardware, advanced system engineering and early
15f8bc67e5Sjeremylt# testbed platforms, in support of the nation's exascale computing imperative.
16f8bc67e5Sjeremylt
17f8bc67e5Sjeremyltfrom _ceed_cffi import ffi, lib
18f8bc67e5Sjeremyltimport ctypes
19f8bc67e5Sjeremyltimport tempfile
20f8bc67e5Sjeremyltfrom abc import ABC
21f8bc67e5Sjeremylt
22f8bc67e5Sjeremylt# ------------------------------------------------------------------------------
237a7b0fa3SJed Brown
247a7b0fa3SJed Brown
25f8bc67e5Sjeremyltclass _QFunctionBase(ABC):
26f8bc67e5Sjeremylt    """Ceed QFunction: point-wise operation at quadrature points for evaluating
27f8bc67e5Sjeremylt         volumetric terms."""
28f8bc67e5Sjeremylt
29f8bc67e5Sjeremylt    # Attributes
30f8bc67e5Sjeremylt    _ceed = ffi.NULL
31f8bc67e5Sjeremylt    _pointer = ffi.NULL
32f8bc67e5Sjeremylt
33f8bc67e5Sjeremylt    # Destructor
34f8bc67e5Sjeremylt    def __del__(self):
35f8bc67e5Sjeremylt        # libCEED call
36*477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionDestroy(self._pointer)
37*477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
38f8bc67e5Sjeremylt
39f8bc67e5Sjeremylt    # Representation
40f8bc67e5Sjeremylt    def __repr__(self):
41f8bc67e5Sjeremylt        return "<CeedQFunction instance at " + hex(id(self)) + ">"
42f8bc67e5Sjeremylt
43f8bc67e5Sjeremylt    # String conversion for print() to stdout
44f8bc67e5Sjeremylt    def __str__(self):
45f8bc67e5Sjeremylt        """View a QFunction via print()."""
46f8bc67e5Sjeremylt
47f8bc67e5Sjeremylt        # libCEED call
48f8bc67e5Sjeremylt        with tempfile.NamedTemporaryFile() as key_file:
49f8bc67e5Sjeremylt            with open(key_file.name, 'r+') as stream_file:
50f8bc67e5Sjeremylt                stream = ffi.cast("FILE *", stream_file)
51f8bc67e5Sjeremylt
52*477729cfSJeremy L Thompson                err_code = lib.CeedQFunctionView(self._pointer[0], stream)
53*477729cfSJeremy L Thompson                self._ceed._check_error(err_code)
54f8bc67e5Sjeremylt
55f8bc67e5Sjeremylt                stream_file.seek(0)
56f8bc67e5Sjeremylt                out_string = stream_file.read()
57f8bc67e5Sjeremylt
58f8bc67e5Sjeremylt        return out_string
59f8bc67e5Sjeremylt
60f8bc67e5Sjeremylt    # Apply CeedQFunction
61f8bc67e5Sjeremylt    def apply(self, q, inputs, outputs):
62f8bc67e5Sjeremylt        """Apply the action of a QFunction.
63f8bc67e5Sjeremylt
64f8bc67e5Sjeremylt           Args:
65f8bc67e5Sjeremylt             q: number of quadrature points
66f8bc67e5Sjeremylt             *inputs: array of input data vectors
67f8bc67e5Sjeremylt             *outputs: array of output data vectors"""
68f8bc67e5Sjeremylt
69f8bc67e5Sjeremylt        # Array of vectors
70f8bc67e5Sjeremylt        invecs = ffi.new("CeedVector[16]")
71f8bc67e5Sjeremylt        for i in range(min(16, len(inputs))):
72f8bc67e5Sjeremylt            invecs[i] = inputs[i]._pointer[0]
73f8bc67e5Sjeremylt        outvecs = ffi.new("CeedVector[16]")
74f8bc67e5Sjeremylt        for i in range(min(16, len(outputs))):
75f8bc67e5Sjeremylt            outvecs[i] = outputs[i]._pointer[0]
76f8bc67e5Sjeremylt
77f8bc67e5Sjeremylt        # libCEED call
78*477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionApply(self._pointer[0], q, invecs, outvecs)
79*477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
80f8bc67e5Sjeremylt
81f8bc67e5Sjeremylt        # Clean-up
82f8bc67e5Sjeremylt        ffi.release(invecs)
83f8bc67e5Sjeremylt        ffi.release(outvecs)
84f8bc67e5Sjeremylt
85f8bc67e5Sjeremylt
86f8bc67e5Sjeremylt# ------------------------------------------------------------------------------
87f8bc67e5Sjeremyltclass QFunction(_QFunctionBase):
88f8bc67e5Sjeremylt    """Ceed QFunction: point-wise operation at quadrature points for evaluating
89f8bc67e5Sjeremylt         volumetric terms."""
90f8bc67e5Sjeremylt
91f8bc67e5Sjeremylt    # Constructor
92f8bc67e5Sjeremylt    def __init__(self, ceed, vlength, f, source):
93f8bc67e5Sjeremylt        # libCEED object
94f8bc67e5Sjeremylt        self._pointer = ffi.new("CeedQFunction *")
95f8bc67e5Sjeremylt
96f8bc67e5Sjeremylt        # Reference to Ceed
97f8bc67e5Sjeremylt        self._ceed = ceed
98f8bc67e5Sjeremylt
99f8bc67e5Sjeremylt        # Function pointer
1007a7b0fa3SJed Brown        fpointer = ffi.cast(
1017a7b0fa3SJed Brown            "CeedQFunctionUser", ctypes.cast(
1027a7b0fa3SJed Brown                f, ctypes.c_void_p).value)
103f8bc67e5Sjeremylt
104f8bc67e5Sjeremylt        # libCEED call
105f8bc67e5Sjeremylt        sourceAscii = ffi.new("char[]", source.encode('ascii'))
106*477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionCreateInterior(self._ceed._pointer[0], vlength,
107*477729cfSJeremy L Thompson                                                   fpointer, sourceAscii, self._pointer)
108*477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
109f8bc67e5Sjeremylt
110f8bc67e5Sjeremylt    # Set context data
111f8bc67e5Sjeremylt    def set_context(self, ctx):
112f8bc67e5Sjeremylt        """Set global context for a QFunction.
113f8bc67e5Sjeremylt
114f8bc67e5Sjeremylt           Args:
115f8bc67e5Sjeremylt             *ctx: Numpy array holding context data to set"""
116f8bc67e5Sjeremylt
117f8bc67e5Sjeremylt        # Setup the numpy array for the libCEED call
118f8bc67e5Sjeremylt        ctx_pointer = ffi.new("CeedScalar *")
119f8bc67e5Sjeremylt        ctx_pointer = ffi.cast("void *", ctx.__array_interface__['data'][0])
120f8bc67e5Sjeremylt
121f8bc67e5Sjeremylt        # libCEED call
122*477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionSetContext(
123*477729cfSJeremy L Thompson            self._pointer[0], ctx_pointer, len(ctx))
124*477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
125f8bc67e5Sjeremylt
126f8bc67e5Sjeremylt    # Add fields to CeedQFunction
127f8bc67e5Sjeremylt    def add_input(self, fieldname, size, emode):
128f8bc67e5Sjeremylt        """Add a QFunction input.
129f8bc67e5Sjeremylt
130f8bc67e5Sjeremylt           Args:
131f8bc67e5Sjeremylt             fieldname: name of QFunction field
132f8bc67e5Sjeremylt             size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or
133f8bc67e5Sjeremylt                     (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP
134f8bc67e5Sjeremylt             **emode: CEED_EVAL_NONE to use values directly,
135f8bc67e5Sjeremylt                      CEED_EVAL_INTERP to use interpolated values,
136f8bc67e5Sjeremylt                      CEED_EVAL_GRAD to use gradients."""
137f8bc67e5Sjeremylt
138f8bc67e5Sjeremylt        # libCEED call
139f8bc67e5Sjeremylt        fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii'))
140*477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionAddInput(
141450bb777Svaleriabarra            self._pointer[0], fieldnameAscii, size, emode)
142*477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
143f8bc67e5Sjeremylt
144f8bc67e5Sjeremylt    def add_output(self, fieldname, size, emode):
145f8bc67e5Sjeremylt        """Add a QFunction output.
146f8bc67e5Sjeremylt
147f8bc67e5Sjeremylt           Args:
148f8bc67e5Sjeremylt             fieldname: name of QFunction field
149f8bc67e5Sjeremylt             size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or
150f8bc67e5Sjeremylt                     (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP
151f8bc67e5Sjeremylt             **emode: CEED_EVAL_NONE to use values directly,
152f8bc67e5Sjeremylt                      CEED_EVAL_INTERP to use interpolated values,
153f8bc67e5Sjeremylt                      CEED_EVAL_GRAD to use gradients."""
154f8bc67e5Sjeremylt
155f8bc67e5Sjeremylt        # libCEED call
156f8bc67e5Sjeremylt        fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii'))
157*477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionAddOutput(
1587a7b0fa3SJed Brown            self._pointer[0], fieldnameAscii, size, emode)
159*477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
160f8bc67e5Sjeremylt
161f8bc67e5Sjeremylt# ------------------------------------------------------------------------------
1627a7b0fa3SJed Brown
1637a7b0fa3SJed Brown
164f8bc67e5Sjeremyltclass QFunctionByName(_QFunctionBase):
165f8bc67e5Sjeremylt    """Ceed QFunction By Name: point-wise operation at quadrature points
166f8bc67e5Sjeremylt         from a given gallery, for evaluating volumetric terms."""
167f8bc67e5Sjeremylt
168f8bc67e5Sjeremylt    # Constructor
169f8bc67e5Sjeremylt    def __init__(self, ceed, name):
170f8bc67e5Sjeremylt        # libCEED object
171f8bc67e5Sjeremylt        self._pointer = ffi.new("CeedQFunction *")
172f8bc67e5Sjeremylt
173f8bc67e5Sjeremylt        # Reference to Ceed
174f8bc67e5Sjeremylt        self._ceed = ceed
175f8bc67e5Sjeremylt
176f8bc67e5Sjeremylt        # libCEED call
177f8bc67e5Sjeremylt        nameAscii = ffi.new("char[]", name.encode('ascii'))
178*477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionCreateInteriorByName(self._ceed._pointer[0],
179*477729cfSJeremy L Thompson                                                         nameAscii, self._pointer)
180*477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
181f8bc67e5Sjeremylt
182f8bc67e5Sjeremylt# ------------------------------------------------------------------------------
1837a7b0fa3SJed Brown
1847a7b0fa3SJed Brown
185f8bc67e5Sjeremyltclass IdentityQFunction(_QFunctionBase):
186f8bc67e5Sjeremylt    """Ceed Identity QFunction: identity qfunction operation."""
187f8bc67e5Sjeremylt
188f8bc67e5Sjeremylt    # Constructor
189f8bc67e5Sjeremylt    def __init__(self, ceed, size, inmode, outmode):
190f8bc67e5Sjeremylt        # libCEED object
191f8bc67e5Sjeremylt        self._pointer = ffi.new("CeedQFunction *")
192f8bc67e5Sjeremylt
193f8bc67e5Sjeremylt        # Reference to Ceed
194f8bc67e5Sjeremylt        self._ceed = ceed
195f8bc67e5Sjeremylt
196f8bc67e5Sjeremylt        # libCEED call
197*477729cfSJeremy L Thompson        err_code = lib.CeedQFunctionCreateIdentity(self._ceed._pointer[0], size,
198*477729cfSJeremy L Thompson                                                   inmode, outmode, self._pointer)
199f8bc67e5Sjeremylt
200f8bc67e5Sjeremylt# ------------------------------------------------------------------------------
201