xref: /libCEED/python/ceed_operator.py (revision 6397b31bcaf7e994aea0d6896897f7cd33505ad1)
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    # Assemble linear diagonal
58    def linear_assemble_diagonal(self, d, request=REQUEST_IMMEDIATE):
59        """Assemble the diagonal of a square linear Operator
60
61           Args:
62             d: Vector to store assembled Operator diagonal
63             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
64
65        # libCEED call
66        lib.CeedOperatorLinearAssembleDiagonal(self._pointer[0],
67            d._pointer[0], request)
68
69    # Assemble add linear diagonal
70    def linear_assemble_add_diagonal(self, d, request=REQUEST_IMMEDIATE):
71        """Sum the diagonal of a square linear Operator into a Vector
72
73           Args:
74             d: Vector to store assembled Operator diagonal
75             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
76
77        # libCEED call
78        lib.CeedOperatorLinearAssembleAddDiagonal(self._pointer[0],
79            d._pointer[0], request)
80
81    # Assemble linear point block diagonal
82    def linear_assemble_point_block_diagonal(self, d, request=REQUEST_IMMEDIATE):
83        """Assemble the diagonal of a square linear Operator
84
85           Args:
86             d: Vector to store assembled Operator point block diagonal,
87                  provided in row-major form with an ncomp*ncomp block
88                  at each node
89             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
90
91        # libCEED call
92        lib.CeedOperatorLinearAssemblePointBlockDiagonal(self._pointer[0],
93            d._pointer[0], request)
94
95    # Assemble linear point block diagonal
96    def linear_assemble_add_point_block_diagonal(self, d, request=REQUEST_IMMEDIATE):
97        """Sum the diagonal of a square linear Operator into a Vector
98
99           Args:
100             d: Vector to store assembled Operator point block diagonal,
101                  provided in row-major form with an ncomp*ncomp block
102                  at each node
103             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
104
105        # libCEED call
106        lib.CeedOperatorLinearAssembleAddPointBlockDiagonal(self._pointer[0],
107            d._pointer[0], request)
108
109    # Apply CeedOperator
110    def apply(self, u, v, request=REQUEST_IMMEDIATE):
111        """Apply Operator to a vector.
112
113           Args:
114             u: Vector containing input state or CEED_VECTOR_NONE if there are no
115                  active inputs
116             v: Vector to store result of applying operator (must be distinct from u)
117                  or CEED_VECTOR_NONE if there are no active outputs
118             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
119
120        # libCEED call
121        lib.CeedOperatorApply(self._pointer[0], u._pointer[0], v._pointer[0],
122                              request)
123
124    # Apply CeedOperator
125    def apply_add(self, u, v, request=REQUEST_IMMEDIATE):
126        """Apply Operator to a vector and add result to output vector.
127
128           Args:
129             u: Vector containing input state or CEED_VECTOR_NONE if there are no
130                  active inputs
131             v: Vector to sum in result of applying operator (must be distinct from u)
132                  or CEED_VECTOR_NONE if there are no active outputs
133             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
134
135        # libCEED call
136        lib.CeedOperatorApplyAdd(self._pointer[0], u._pointer[0], v._pointer[0],
137                                 request)
138
139# ------------------------------------------------------------------------------
140
141
142class Operator(_OperatorBase):
143    """Ceed Operator: composed FE-type operations on vectors."""
144
145    # Constructor
146    def __init__(self, ceed, qf, dqf=None, dqfT=None):
147        # CeedOperator object
148        self._pointer = ffi.new("CeedOperator *")
149
150        # Reference to Ceed
151        self._ceed = ceed
152
153        # libCEED call
154        lib.CeedOperatorCreate(self._ceed._pointer[0], qf._pointer[0],
155                               dqf._pointer[0] if dqf else ffi.NULL,
156                               dqfT._pointer[0] if dqfT else ffi.NULL,
157                               self._pointer)
158
159    # Add field to CeedOperator
160    def set_field(self, fieldname, restriction, basis, vector):
161        """Provide a field to an Operator for use by its QFunction.
162
163           Args:
164             fieldname: name of the field (to be matched with the same name used
165                          by QFunction)
166             restriction: ElemRestriction
167             basis: Basis in which the field resides or CEED_BASIS_COLLOCATED
168                      if collocated with quadrature points
169             vector: Vector to be used by Operator or CEED_VECTOR_ACTIVE
170                       if field is active or CEED_VECTOR_NONE if using
171                       CEED_EVAL_WEIGHT in the QFunction"""
172
173        # libCEED call
174        fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii'))
175        lib.CeedOperatorSetField(self._pointer[0], fieldnameAscii,
176                                 restriction._pointer[0], basis._pointer[0],
177                                 vector._pointer[0])
178
179# ------------------------------------------------------------------------------
180
181
182class CompositeOperator(_OperatorBase):
183    """Ceed Composite Operator: composition of multiple Operators."""
184
185    # Constructor
186    def __init__(self, ceed):
187        # CeedOperator object
188        self._pointer = ffi.new("CeedOperator *")
189
190        # Reference to Ceed
191        self._ceed = ceed
192        # libCEED call
193        lib.CeedCompositeOperatorCreate(self._ceed._pointer[0], self._pointer)
194
195    # Add sub operators
196    def add_sub(self, subop):
197        """Add a sub-operator to a composite CeedOperator.
198
199           Args:
200             subop: sub-operator Operator"""
201
202        # libCEED call
203        lib.CeedCompositeOperatorAddSub(self._pointer[0], subop._pointer[0])
204
205# ------------------------------------------------------------------------------
206