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 36*477729cfSJeremy L Thompson err_code = lib.CeedQFunctionDestroy(self._pointer) 37*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 38f8bc67e5Sjeremylt 39f8bc67e5Sjeremylt # Representation 40f8bc67e5Sjeremylt def __repr__(self): 41f8bc67e5Sjeremylt return "<CeedQFunction instance at " + hex(id(self)) + ">" 42f8bc67e5Sjeremylt 43f8bc67e5Sjeremylt # String conversion for print() to stdout 44f8bc67e5Sjeremylt def __str__(self): 45f8bc67e5Sjeremylt """View a QFunction via print().""" 46f8bc67e5Sjeremylt 47f8bc67e5Sjeremylt # libCEED call 48f8bc67e5Sjeremylt with tempfile.NamedTemporaryFile() as key_file: 49f8bc67e5Sjeremylt with open(key_file.name, 'r+') as stream_file: 50f8bc67e5Sjeremylt stream = ffi.cast("FILE *", stream_file) 51f8bc67e5Sjeremylt 52*477729cfSJeremy L Thompson err_code = lib.CeedQFunctionView(self._pointer[0], stream) 53*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 54f8bc67e5Sjeremylt 55f8bc67e5Sjeremylt stream_file.seek(0) 56f8bc67e5Sjeremylt out_string = stream_file.read() 57f8bc67e5Sjeremylt 58f8bc67e5Sjeremylt return out_string 59f8bc67e5Sjeremylt 60f8bc67e5Sjeremylt # Apply CeedQFunction 61f8bc67e5Sjeremylt def apply(self, q, inputs, outputs): 62f8bc67e5Sjeremylt """Apply the action of a QFunction. 63f8bc67e5Sjeremylt 64f8bc67e5Sjeremylt Args: 65f8bc67e5Sjeremylt q: number of quadrature points 66f8bc67e5Sjeremylt *inputs: array of input data vectors 67f8bc67e5Sjeremylt *outputs: array of output data vectors""" 68f8bc67e5Sjeremylt 69f8bc67e5Sjeremylt # Array of vectors 70f8bc67e5Sjeremylt invecs = ffi.new("CeedVector[16]") 71f8bc67e5Sjeremylt for i in range(min(16, len(inputs))): 72f8bc67e5Sjeremylt invecs[i] = inputs[i]._pointer[0] 73f8bc67e5Sjeremylt outvecs = ffi.new("CeedVector[16]") 74f8bc67e5Sjeremylt for i in range(min(16, len(outputs))): 75f8bc67e5Sjeremylt outvecs[i] = outputs[i]._pointer[0] 76f8bc67e5Sjeremylt 77f8bc67e5Sjeremylt # libCEED call 78*477729cfSJeremy L Thompson err_code = lib.CeedQFunctionApply(self._pointer[0], q, invecs, outvecs) 79*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 80f8bc67e5Sjeremylt 81f8bc67e5Sjeremylt # Clean-up 82f8bc67e5Sjeremylt ffi.release(invecs) 83f8bc67e5Sjeremylt ffi.release(outvecs) 84f8bc67e5Sjeremylt 85f8bc67e5Sjeremylt 86f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 87f8bc67e5Sjeremyltclass QFunction(_QFunctionBase): 88f8bc67e5Sjeremylt """Ceed QFunction: point-wise operation at quadrature points for evaluating 89f8bc67e5Sjeremylt volumetric terms.""" 90f8bc67e5Sjeremylt 91f8bc67e5Sjeremylt # Constructor 92f8bc67e5Sjeremylt def __init__(self, ceed, vlength, f, source): 93f8bc67e5Sjeremylt # libCEED object 94f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 95f8bc67e5Sjeremylt 96f8bc67e5Sjeremylt # Reference to Ceed 97f8bc67e5Sjeremylt self._ceed = ceed 98f8bc67e5Sjeremylt 99f8bc67e5Sjeremylt # Function pointer 1007a7b0fa3SJed Brown fpointer = ffi.cast( 1017a7b0fa3SJed Brown "CeedQFunctionUser", ctypes.cast( 1027a7b0fa3SJed Brown f, ctypes.c_void_p).value) 103f8bc67e5Sjeremylt 104f8bc67e5Sjeremylt # libCEED call 105f8bc67e5Sjeremylt sourceAscii = ffi.new("char[]", source.encode('ascii')) 106*477729cfSJeremy L Thompson err_code = lib.CeedQFunctionCreateInterior(self._ceed._pointer[0], vlength, 107*477729cfSJeremy L Thompson fpointer, sourceAscii, self._pointer) 108*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 109f8bc67e5Sjeremylt 110f8bc67e5Sjeremylt # Set context data 111f8bc67e5Sjeremylt def set_context(self, ctx): 112f8bc67e5Sjeremylt """Set global context for a QFunction. 113f8bc67e5Sjeremylt 114f8bc67e5Sjeremylt Args: 115f8bc67e5Sjeremylt *ctx: Numpy array holding context data to set""" 116f8bc67e5Sjeremylt 117f8bc67e5Sjeremylt # Setup the numpy array for the libCEED call 118f8bc67e5Sjeremylt ctx_pointer = ffi.new("CeedScalar *") 119f8bc67e5Sjeremylt ctx_pointer = ffi.cast("void *", ctx.__array_interface__['data'][0]) 120f8bc67e5Sjeremylt 121f8bc67e5Sjeremylt # libCEED call 122*477729cfSJeremy L Thompson err_code = lib.CeedQFunctionSetContext( 123*477729cfSJeremy L Thompson self._pointer[0], ctx_pointer, len(ctx)) 124*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 125f8bc67e5Sjeremylt 126f8bc67e5Sjeremylt # Add fields to CeedQFunction 127f8bc67e5Sjeremylt def add_input(self, fieldname, size, emode): 128f8bc67e5Sjeremylt """Add a QFunction input. 129f8bc67e5Sjeremylt 130f8bc67e5Sjeremylt Args: 131f8bc67e5Sjeremylt fieldname: name of QFunction field 132f8bc67e5Sjeremylt size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 133f8bc67e5Sjeremylt (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP 134f8bc67e5Sjeremylt **emode: CEED_EVAL_NONE to use values directly, 135f8bc67e5Sjeremylt CEED_EVAL_INTERP to use interpolated values, 136f8bc67e5Sjeremylt CEED_EVAL_GRAD to use gradients.""" 137f8bc67e5Sjeremylt 138f8bc67e5Sjeremylt # libCEED call 139f8bc67e5Sjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 140*477729cfSJeremy L Thompson err_code = lib.CeedQFunctionAddInput( 141450bb777Svaleriabarra self._pointer[0], fieldnameAscii, size, emode) 142*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 143f8bc67e5Sjeremylt 144f8bc67e5Sjeremylt def add_output(self, fieldname, size, emode): 145f8bc67e5Sjeremylt """Add a QFunction output. 146f8bc67e5Sjeremylt 147f8bc67e5Sjeremylt Args: 148f8bc67e5Sjeremylt fieldname: name of QFunction field 149f8bc67e5Sjeremylt size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 150f8bc67e5Sjeremylt (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP 151f8bc67e5Sjeremylt **emode: CEED_EVAL_NONE to use values directly, 152f8bc67e5Sjeremylt CEED_EVAL_INTERP to use interpolated values, 153f8bc67e5Sjeremylt CEED_EVAL_GRAD to use gradients.""" 154f8bc67e5Sjeremylt 155f8bc67e5Sjeremylt # libCEED call 156f8bc67e5Sjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 157*477729cfSJeremy L Thompson err_code = lib.CeedQFunctionAddOutput( 1587a7b0fa3SJed Brown self._pointer[0], fieldnameAscii, size, emode) 159*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 160f8bc67e5Sjeremylt 161f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 1627a7b0fa3SJed Brown 1637a7b0fa3SJed Brown 164f8bc67e5Sjeremyltclass QFunctionByName(_QFunctionBase): 165f8bc67e5Sjeremylt """Ceed QFunction By Name: point-wise operation at quadrature points 166f8bc67e5Sjeremylt from a given gallery, for evaluating volumetric terms.""" 167f8bc67e5Sjeremylt 168f8bc67e5Sjeremylt # Constructor 169f8bc67e5Sjeremylt def __init__(self, ceed, name): 170f8bc67e5Sjeremylt # libCEED object 171f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 172f8bc67e5Sjeremylt 173f8bc67e5Sjeremylt # Reference to Ceed 174f8bc67e5Sjeremylt self._ceed = ceed 175f8bc67e5Sjeremylt 176f8bc67e5Sjeremylt # libCEED call 177f8bc67e5Sjeremylt nameAscii = ffi.new("char[]", name.encode('ascii')) 178*477729cfSJeremy L Thompson err_code = lib.CeedQFunctionCreateInteriorByName(self._ceed._pointer[0], 179*477729cfSJeremy L Thompson nameAscii, self._pointer) 180*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 181f8bc67e5Sjeremylt 182f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 1837a7b0fa3SJed Brown 1847a7b0fa3SJed Brown 185f8bc67e5Sjeremyltclass IdentityQFunction(_QFunctionBase): 186f8bc67e5Sjeremylt """Ceed Identity QFunction: identity qfunction operation.""" 187f8bc67e5Sjeremylt 188f8bc67e5Sjeremylt # Constructor 189f8bc67e5Sjeremylt def __init__(self, ceed, size, inmode, outmode): 190f8bc67e5Sjeremylt # libCEED object 191f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 192f8bc67e5Sjeremylt 193f8bc67e5Sjeremylt # Reference to Ceed 194f8bc67e5Sjeremylt self._ceed = ceed 195f8bc67e5Sjeremylt 196f8bc67e5Sjeremylt # libCEED call 197*477729cfSJeremy L Thompson err_code = lib.CeedQFunctionCreateIdentity(self._ceed._pointer[0], size, 198*477729cfSJeremy L Thompson inmode, outmode, self._pointer) 199f8bc67e5Sjeremylt 200f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 201