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