xref: /libCEED/python/ceed_operator.py (revision ab213215e569729a95fd10d21627f8060eaeb868)
1# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3# reserved. See files LICENSE and NOTICE for details.
4#
5# This file is part of CEED, a collection of benchmarks, miniapps, software
6# libraries and APIs for efficient high-order finite element and spectral
7# element discretizations for exascale applications. For more information and
8# source code availability see http://github.com/ceed.
9#
10# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11# a collaborative effort of two U.S. Department of Energy organizations (Office
12# of Science and the National Nuclear Security Administration) responsible for
13# the planning and preparation of a capable exascale ecosystem, including
14# software, applications, hardware, advanced system engineering and early
15# testbed platforms, in support of the nation's exascale computing imperative.
16
17from _ceed_cffi import ffi, lib
18import tempfile
19from abc import ABC
20from .ceed_constants import REQUEST_IMMEDIATE, REQUEST_ORDERED, NOTRANSPOSE
21
22# ------------------------------------------------------------------------------
23
24
25class _OperatorBase(ABC):
26    """Ceed Operator: composed FE-type operations on vectors."""
27
28    # Attributes
29    _ceed = ffi.NULL
30    _pointer = ffi.NULL
31
32    # Destructor
33    def __del__(self):
34        # libCEED call
35        lib.CeedOperatorDestroy(self._pointer)
36
37    # Representation
38    def __repr__(self):
39        return "<CeedOperator instance at " + hex(id(self)) + ">"
40
41    # String conversion for print() to stdout
42    def __str__(self):
43        """View an Operator via print()."""
44
45        # libCEED call
46        with tempfile.NamedTemporaryFile() as key_file:
47            with open(key_file.name, 'r+') as stream_file:
48                stream = ffi.cast("FILE *", stream_file)
49
50                lib.CeedOperatorView(self._pointer[0], stream)
51
52                stream_file.seek(0)
53                out_string = stream_file.read()
54
55        return out_string
56
57    # Apply CeedOperator
58    def apply(self, u, v, request=REQUEST_IMMEDIATE):
59        """Apply Operator to a vector.
60
61           Args:
62             u: Vector containing input state or CEED_VECTOR_NONE if there are no
63                  active inputs
64             v: Vector to store result of applying operator (must be distinct from u)
65                  or CEED_VECTOR_NONE if there are no active outputs
66             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
67
68        # libCEED call
69        lib.CeedOperatorApply(self._pointer[0], u._pointer[0], v._pointer[0],
70                              request)
71
72    # Apply CeedOperator
73    def apply_add(self, u, v, request=REQUEST_IMMEDIATE):
74        """Apply Operator to a vector and add result to output vector.
75
76           Args:
77             u: Vector containing input state or CEED_VECTOR_NONE if there are no
78                  active inputs
79             v: Vector to sum in result of applying operator (must be distinct from u)
80                  or CEED_VECTOR_NONE if there are no active outputs
81             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
82
83        # libCEED call
84        lib.CeedOperatorApplyAdd(self._pointer[0], u._pointer[0], v._pointer[0],
85                                 request)
86
87# ------------------------------------------------------------------------------
88
89
90class Operator(_OperatorBase):
91    """Ceed Operator: composed FE-type operations on vectors."""
92
93    # Constructor
94    def __init__(self, ceed, qf, dqf=None, dqfT=None):
95        # CeedOperator object
96        self._pointer = ffi.new("CeedOperator *")
97
98        # Reference to Ceed
99        self._ceed = ceed
100
101        # libCEED call
102        lib.CeedOperatorCreate(self._ceed._pointer[0], qf._pointer[0],
103                               dqf._pointer[0] if dqf else ffi.NULL,
104                               dqfT._pointer[0] if dqfT else ffi.NULL,
105                               self._pointer)
106
107    # Add field to CeedOperator
108    def set_field(self, fieldname, restriction, basis, vector):
109        """Provide a field to an Operator for use by its QFunction.
110
111           Args:
112             fieldname: name of the field (to be matched with the same name used
113                          by QFunction)
114             restriction: ElemRestriction
115             basis: Basis in which the field resides or CEED_BASIS_COLLOCATED
116                      if collocated with quadrature points
117             vector: Vector to be used by Operator or CEED_VECTOR_ACTIVE
118                       if field is active or CEED_VECTOR_NONE if using
119                       CEED_EVAL_WEIGHT in the QFunction"""
120
121        # libCEED call
122        fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii'))
123        lib.CeedOperatorSetField(self._pointer[0], fieldnameAscii,
124                                 restriction._pointer[0], basis._pointer[0],
125                                 vector._pointer[0])
126
127# ------------------------------------------------------------------------------
128
129
130class CompositeOperator(_OperatorBase):
131    """Ceed Composite Operator: composition of multiple Operators."""
132
133    # Constructor
134    def __init__(self, ceed):
135        # CeedOperator object
136        self._pointer = ffi.new("CeedOperator *")
137
138        # Reference to Ceed
139        self._ceed = ceed
140        # libCEED call
141        lib.CeedCompositeOperatorCreate(self._ceed._pointer[0], self._pointer)
142
143    # Add sub operators
144    def add_sub(self, subop):
145        """Add a sub-operator to a composite CeedOperator.
146
147           Args:
148             subop: sub-operator Operator"""
149
150        # libCEED call
151        lib.CeedCompositeOperatorAddSub(self._pointer[0], subop._pointer[0])
152
153# ------------------------------------------------------------------------------
154