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