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