xref: /libCEED/python/ceed_operator.py (revision b0812a454286a178b5527bf1d1f1a428af10126c)
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# ------------------------------------------------------------------------------
23class _OperatorBase(ABC):
24  """Ceed Operator: composed FE-type operations on vectors."""
25
26  # Attributes
27  _ceed = ffi.NULL
28  _pointer = ffi.NULL
29
30  # Destructor
31  def __del__(self):
32    # libCEED call
33    lib.CeedOperatorDestroy(self._pointer)
34
35  # Representation
36  def __repr__(self):
37    return "<CeedOperator instance at " + hex(id(self)) + ">"
38
39  # String conversion for print() to stdout
40  def __str__(self):
41    """View an Operator via print()."""
42
43    # libCEED call
44    with tempfile.NamedTemporaryFile() as key_file:
45      with open(key_file.name, 'r+') as stream_file:
46        stream = ffi.cast("FILE *", stream_file)
47
48        lib.CeedOperatorView(self._pointer[0], stream)
49
50        stream_file.seek(0)
51        out_string = stream_file.read()
52
53    return out_string
54
55  # Apply CeedOperator
56  def apply(self, u, v, request=REQUEST_IMMEDIATE):
57    """Apply Operator to a vector.
58
59       Args:
60         u: Vector containing input state or CEED_VECTOR_NONE if there are no
61              active inputs
62         v: Vector to store result of applying operator (must be distinct from u)
63              or CEED_VECTOR_NONE if there are no active outputs
64         **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
65
66    # libCEED call
67    lib.CeedOperatorApply(self._pointer[0], u._pointer[0], v._pointer[0],
68                          request)
69
70  # Apply CeedOperator
71  def apply_add(self, u, v, request=REQUEST_IMMEDIATE):
72    """Apply Operator to a vector and add result to output vector.
73
74       Args:
75         u: Vector containing input state or CEED_VECTOR_NONE if there are no
76              active inputs
77         v: Vector to sum in result of applying operator (must be distinct from u)
78              or CEED_VECTOR_NONE if there are no active outputs
79         **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
80
81    # libCEED call
82    lib.CeedOperatorApplyAdd(self._pointer[0], u._pointer[0], v._pointer[0],
83                             request)
84
85# ------------------------------------------------------------------------------
86class Operator(_OperatorBase):
87  """Ceed Operator: composed FE-type operations on vectors."""
88
89  # Constructor
90  def __init__(self, ceed, qf, dqf = None, dqfT = None):
91    # CeedOperator object
92    self._pointer = ffi.new("CeedOperator *")
93
94    # Reference to Ceed
95    self._ceed = ceed
96
97    # libCEED call
98    lib.CeedOperatorCreate(self._ceed._pointer[0], qf._pointer[0],
99                           dqf._pointer[0] if dqf else ffi.NULL,
100                           dqfT._pointer[0] if dqfT else ffi.NULL,
101                           self._pointer)
102
103  # Add field to CeedOperator
104  def set_field(self, fieldname, restriction, basis, vector):
105    """Provide a field to an Operator for use by its QFunction.
106
107       Args:
108         fieldname: name of the field (to be matched with the same name used
109                      by QFunction)
110         restriction: ElemRestriction
111         basis: Basis in which the field resides or CEED_BASIS_COLLOCATED
112                  if collocated with quadrature points
113         vector: Vector to be used by Operator or CEED_VECTOR_ACTIVE
114                   if field is active or CEED_VECTOR_NONE if using
115                   CEED_EVAL_WEIGHT in the QFunction"""
116
117    # libCEED call
118    fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii'))
119    lib.CeedOperatorSetField(self._pointer[0], fieldnameAscii,
120                             restriction._pointer[0], basis._pointer[0],
121                             vector._pointer[0])
122
123# ------------------------------------------------------------------------------
124class CompositeOperator(_OperatorBase):
125  """Ceed Composite Operator: composition of multiple Operators."""
126
127  # Constructor
128  def __init__(self, ceed):
129    # CeedOperator object
130    self._pointer = ffi.new("CeedOperator *")
131
132    # Reference to Ceed
133    self._ceed = ceed
134    # libCEED call
135    lib.CeedCompositeOperatorCreate(self._ceed._pointer[0], self._pointer)
136
137  # Add sub operators
138  def add_sub(self, subop):
139    """Add a sub-operator to a composite CeedOperator.
140
141       Args:
142         subop: sub-operator Operator"""
143
144    # libCEED call
145    lib.CeedCompositeOperatorAddSub(self._pointer[0], subop._pointer[0])
146
147# ------------------------------------------------------------------------------
148