1*f8bc67e5Sjeremylt# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2*f8bc67e5Sjeremylt# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3*f8bc67e5Sjeremylt# reserved. See files LICENSE and NOTICE for details. 4*f8bc67e5Sjeremylt# 5*f8bc67e5Sjeremylt# This file is part of CEED, a collection of benchmarks, miniapps, software 6*f8bc67e5Sjeremylt# libraries and APIs for efficient high-order finite element and spectral 7*f8bc67e5Sjeremylt# element discretizations for exascale applications. For more information and 8*f8bc67e5Sjeremylt# source code availability see http://github.com/ceed. 9*f8bc67e5Sjeremylt# 10*f8bc67e5Sjeremylt# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11*f8bc67e5Sjeremylt# a collaborative effort of two U.S. Department of Energy organizations (Office 12*f8bc67e5Sjeremylt# of Science and the National Nuclear Security Administration) responsible for 13*f8bc67e5Sjeremylt# the planning and preparation of a capable exascale ecosystem, including 14*f8bc67e5Sjeremylt# software, applications, hardware, advanced system engineering and early 15*f8bc67e5Sjeremylt# testbed platforms, in support of the nation's exascale computing imperative. 16*f8bc67e5Sjeremylt 17*f8bc67e5Sjeremyltfrom _ceed_cffi import ffi, lib 18*f8bc67e5Sjeremyltimport ctypes 19*f8bc67e5Sjeremyltimport tempfile 20*f8bc67e5Sjeremyltfrom abc import ABC 21*f8bc67e5Sjeremylt 22*f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 23*f8bc67e5Sjeremyltclass _QFunctionBase(ABC): 24*f8bc67e5Sjeremylt """Ceed QFunction: point-wise operation at quadrature points for evaluating 25*f8bc67e5Sjeremylt volumetric terms.""" 26*f8bc67e5Sjeremylt 27*f8bc67e5Sjeremylt # Attributes 28*f8bc67e5Sjeremylt _ceed = ffi.NULL 29*f8bc67e5Sjeremylt _pointer = ffi.NULL 30*f8bc67e5Sjeremylt 31*f8bc67e5Sjeremylt # Destructor 32*f8bc67e5Sjeremylt def __del__(self): 33*f8bc67e5Sjeremylt # libCEED call 34*f8bc67e5Sjeremylt lib.CeedQFunctionDestroy(self._pointer) 35*f8bc67e5Sjeremylt 36*f8bc67e5Sjeremylt # Representation 37*f8bc67e5Sjeremylt def __repr__(self): 38*f8bc67e5Sjeremylt return "<CeedQFunction instance at " + hex(id(self)) + ">" 39*f8bc67e5Sjeremylt 40*f8bc67e5Sjeremylt # String conversion for print() to stdout 41*f8bc67e5Sjeremylt def __str__(self): 42*f8bc67e5Sjeremylt """View a QFunction via print().""" 43*f8bc67e5Sjeremylt 44*f8bc67e5Sjeremylt # libCEED call 45*f8bc67e5Sjeremylt with tempfile.NamedTemporaryFile() as key_file: 46*f8bc67e5Sjeremylt with open(key_file.name, 'r+') as stream_file: 47*f8bc67e5Sjeremylt stream = ffi.cast("FILE *", stream_file) 48*f8bc67e5Sjeremylt 49*f8bc67e5Sjeremylt lib.CeedQFunctionView(self._pointer[0], stream) 50*f8bc67e5Sjeremylt 51*f8bc67e5Sjeremylt stream_file.seek(0) 52*f8bc67e5Sjeremylt out_string = stream_file.read() 53*f8bc67e5Sjeremylt 54*f8bc67e5Sjeremylt return out_string 55*f8bc67e5Sjeremylt 56*f8bc67e5Sjeremylt # Apply CeedQFunction 57*f8bc67e5Sjeremylt def apply(self, q, inputs, outputs): 58*f8bc67e5Sjeremylt """Apply the action of a QFunction. 59*f8bc67e5Sjeremylt 60*f8bc67e5Sjeremylt Args: 61*f8bc67e5Sjeremylt q: number of quadrature points 62*f8bc67e5Sjeremylt *inputs: array of input data vectors 63*f8bc67e5Sjeremylt *outputs: array of output data vectors""" 64*f8bc67e5Sjeremylt 65*f8bc67e5Sjeremylt # Array of vectors 66*f8bc67e5Sjeremylt invecs = ffi.new("CeedVector[16]") 67*f8bc67e5Sjeremylt for i in range(min(16, len(inputs))): 68*f8bc67e5Sjeremylt invecs[i] = inputs[i]._pointer[0] 69*f8bc67e5Sjeremylt outvecs = ffi.new("CeedVector[16]") 70*f8bc67e5Sjeremylt for i in range(min(16, len(outputs))): 71*f8bc67e5Sjeremylt outvecs[i] = outputs[i]._pointer[0] 72*f8bc67e5Sjeremylt 73*f8bc67e5Sjeremylt # libCEED call 74*f8bc67e5Sjeremylt lib.CeedQFunctionApply(self._pointer[0], q, invecs, outvecs) 75*f8bc67e5Sjeremylt 76*f8bc67e5Sjeremylt # Clean-up 77*f8bc67e5Sjeremylt ffi.release(invecs) 78*f8bc67e5Sjeremylt ffi.release(outvecs) 79*f8bc67e5Sjeremylt 80*f8bc67e5Sjeremylt 81*f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 82*f8bc67e5Sjeremyltclass QFunction(_QFunctionBase): 83*f8bc67e5Sjeremylt """Ceed QFunction: point-wise operation at quadrature points for evaluating 84*f8bc67e5Sjeremylt volumetric terms.""" 85*f8bc67e5Sjeremylt 86*f8bc67e5Sjeremylt # Constructor 87*f8bc67e5Sjeremylt def __init__(self, ceed, vlength, f, source): 88*f8bc67e5Sjeremylt # libCEED object 89*f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 90*f8bc67e5Sjeremylt 91*f8bc67e5Sjeremylt # Reference to Ceed 92*f8bc67e5Sjeremylt self._ceed = ceed 93*f8bc67e5Sjeremylt 94*f8bc67e5Sjeremylt # Function pointer 95*f8bc67e5Sjeremylt fpointer = ffi.cast("CeedQFunctionUser", ctypes.cast(f, ctypes.c_void_p).value) 96*f8bc67e5Sjeremylt 97*f8bc67e5Sjeremylt # libCEED call 98*f8bc67e5Sjeremylt sourceAscii = ffi.new("char[]", source.encode('ascii')) 99*f8bc67e5Sjeremylt lib.CeedQFunctionCreateInterior(self._ceed._pointer[0], vlength, fpointer, 100*f8bc67e5Sjeremylt sourceAscii, self._pointer) 101*f8bc67e5Sjeremylt 102*f8bc67e5Sjeremylt # Set context data 103*f8bc67e5Sjeremylt def set_context(self, ctx): 104*f8bc67e5Sjeremylt """Set global context for a QFunction. 105*f8bc67e5Sjeremylt 106*f8bc67e5Sjeremylt Args: 107*f8bc67e5Sjeremylt *ctx: Numpy array holding context data to set""" 108*f8bc67e5Sjeremylt 109*f8bc67e5Sjeremylt # Setup the numpy array for the libCEED call 110*f8bc67e5Sjeremylt ctx_pointer = ffi.new("CeedScalar *") 111*f8bc67e5Sjeremylt ctx_pointer = ffi.cast("void *", ctx.__array_interface__['data'][0]) 112*f8bc67e5Sjeremylt 113*f8bc67e5Sjeremylt # libCEED call 114*f8bc67e5Sjeremylt lib.CeedQFunctionSetContext(self._pointer[0], ctx_pointer, len(ctx)) 115*f8bc67e5Sjeremylt 116*f8bc67e5Sjeremylt # Add fields to CeedQFunction 117*f8bc67e5Sjeremylt def add_input(self, fieldname, size, emode): 118*f8bc67e5Sjeremylt """Add a QFunction input. 119*f8bc67e5Sjeremylt 120*f8bc67e5Sjeremylt Args: 121*f8bc67e5Sjeremylt fieldname: name of QFunction field 122*f8bc67e5Sjeremylt size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 123*f8bc67e5Sjeremylt (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP 124*f8bc67e5Sjeremylt **emode: CEED_EVAL_NONE to use values directly, 125*f8bc67e5Sjeremylt CEED_EVAL_INTERP to use interpolated values, 126*f8bc67e5Sjeremylt CEED_EVAL_GRAD to use gradients.""" 127*f8bc67e5Sjeremylt 128*f8bc67e5Sjeremylt # libCEED call 129*f8bc67e5Sjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 130*f8bc67e5Sjeremylt lib.CeedQFunctionAddInput(self._pointer[0], fieldnameAscii, size, emode) 131*f8bc67e5Sjeremylt 132*f8bc67e5Sjeremylt def add_output(self, fieldname, size, emode): 133*f8bc67e5Sjeremylt """Add a QFunction output. 134*f8bc67e5Sjeremylt 135*f8bc67e5Sjeremylt Args: 136*f8bc67e5Sjeremylt fieldname: name of QFunction field 137*f8bc67e5Sjeremylt size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 138*f8bc67e5Sjeremylt (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP 139*f8bc67e5Sjeremylt **emode: CEED_EVAL_NONE to use values directly, 140*f8bc67e5Sjeremylt CEED_EVAL_INTERP to use interpolated values, 141*f8bc67e5Sjeremylt CEED_EVAL_GRAD to use gradients.""" 142*f8bc67e5Sjeremylt 143*f8bc67e5Sjeremylt # libCEED call 144*f8bc67e5Sjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 145*f8bc67e5Sjeremylt lib.CeedQFunctionAddOutput(self._pointer[0], fieldnameAscii, size, emode) 146*f8bc67e5Sjeremylt 147*f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 148*f8bc67e5Sjeremyltclass QFunctionByName(_QFunctionBase): 149*f8bc67e5Sjeremylt """Ceed QFunction By Name: point-wise operation at quadrature points 150*f8bc67e5Sjeremylt from a given gallery, for evaluating volumetric terms.""" 151*f8bc67e5Sjeremylt 152*f8bc67e5Sjeremylt # Constructor 153*f8bc67e5Sjeremylt def __init__(self, ceed, name): 154*f8bc67e5Sjeremylt # libCEED object 155*f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 156*f8bc67e5Sjeremylt 157*f8bc67e5Sjeremylt # Reference to Ceed 158*f8bc67e5Sjeremylt self._ceed = ceed 159*f8bc67e5Sjeremylt 160*f8bc67e5Sjeremylt # libCEED call 161*f8bc67e5Sjeremylt nameAscii = ffi.new("char[]", name.encode('ascii')) 162*f8bc67e5Sjeremylt lib.CeedQFunctionCreateInteriorByName(self._ceed._pointer[0], nameAscii, 163*f8bc67e5Sjeremylt self._pointer) 164*f8bc67e5Sjeremylt 165*f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 166*f8bc67e5Sjeremyltclass IdentityQFunction(_QFunctionBase): 167*f8bc67e5Sjeremylt """Ceed Identity QFunction: identity qfunction operation.""" 168*f8bc67e5Sjeremylt 169*f8bc67e5Sjeremylt # Constructor 170*f8bc67e5Sjeremylt def __init__(self, ceed, size, inmode, outmode): 171*f8bc67e5Sjeremylt # libCEED object 172*f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 173*f8bc67e5Sjeremylt 174*f8bc67e5Sjeremylt # Reference to Ceed 175*f8bc67e5Sjeremylt self._ceed = ceed 176*f8bc67e5Sjeremylt 177*f8bc67e5Sjeremylt # libCEED call 178*f8bc67e5Sjeremylt lib.CeedQFunctionCreateIdentity(self._ceed._pointer[0], size, inmode, 179*f8bc67e5Sjeremylt outmode, self._pointer) 180*f8bc67e5Sjeremylt 181*f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 182