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, lmode=NOTRANSPOSE): 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 **lmode: CeedTransposeMode which specifies the ordering of the 117 components of the l-vector used by this CeedOperatorField, 118 CEED_NOTRANSPOSE indicates the component is the 119 outermost index and CEED_TRANSPOSE indicates the component 120 is the innermost index in ordering of the local vector, 121 default CEED_NOTRANSPOSE""" 122 123 # libCEED call 124 fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 125 lib.CeedOperatorSetField(self._pointer[0], fieldnameAscii, 126 restriction._pointer[0], lmode, basis._pointer[0], 127 vector._pointer[0]) 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