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 36477729cfSJeremy L Thompson err_code = lib.CeedQFunctionDestroy(self._pointer) 37477729cfSJeremy 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 52477729cfSJeremy L Thompson err_code = lib.CeedQFunctionView(self._pointer[0], stream) 53477729cfSJeremy 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 78477729cfSJeremy L Thompson err_code = lib.CeedQFunctionApply(self._pointer[0], q, invecs, outvecs) 79477729cfSJeremy 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')) 106477729cfSJeremy L Thompson err_code = lib.CeedQFunctionCreateInterior(self._ceed._pointer[0], vlength, 107477729cfSJeremy L Thompson fpointer, sourceAscii, self._pointer) 108477729cfSJeremy 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: 115*777ff853SJeremy L Thompson ctx: Ceed User Context object holding context data""" 116f8bc67e5Sjeremylt 117f8bc67e5Sjeremylt # libCEED call 118477729cfSJeremy L Thompson err_code = lib.CeedQFunctionSetContext( 119*777ff853SJeremy L Thompson self._pointer[0], 120*777ff853SJeremy L Thompson ctx._pointer[0]) 121477729cfSJeremy L Thompson self._ceed._check_error(err_code) 122f8bc67e5Sjeremylt 123f8bc67e5Sjeremylt # Add fields to CeedQFunction 124f8bc67e5Sjeremylt def add_input(self, fieldname, size, emode): 125f8bc67e5Sjeremylt """Add a QFunction input. 126f8bc67e5Sjeremylt 127f8bc67e5Sjeremylt Args: 128f8bc67e5Sjeremylt fieldname: name of QFunction field 129f8bc67e5Sjeremylt size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 130f8bc67e5Sjeremylt (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP 131f8bc67e5Sjeremylt **emode: CEED_EVAL_NONE to use values directly, 132f8bc67e5Sjeremylt CEED_EVAL_INTERP to use interpolated values, 133f8bc67e5Sjeremylt CEED_EVAL_GRAD to use gradients.""" 134f8bc67e5Sjeremylt 135f8bc67e5Sjeremylt # libCEED call 136f8bc67e5Sjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 137477729cfSJeremy L Thompson err_code = lib.CeedQFunctionAddInput( 138450bb777Svaleriabarra self._pointer[0], fieldnameAscii, size, emode) 139477729cfSJeremy L Thompson self._ceed._check_error(err_code) 140f8bc67e5Sjeremylt 141f8bc67e5Sjeremylt def add_output(self, fieldname, size, emode): 142f8bc67e5Sjeremylt """Add a QFunction output. 143f8bc67e5Sjeremylt 144f8bc67e5Sjeremylt Args: 145f8bc67e5Sjeremylt fieldname: name of QFunction field 146f8bc67e5Sjeremylt size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 147f8bc67e5Sjeremylt (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP 148f8bc67e5Sjeremylt **emode: CEED_EVAL_NONE to use values directly, 149f8bc67e5Sjeremylt CEED_EVAL_INTERP to use interpolated values, 150f8bc67e5Sjeremylt CEED_EVAL_GRAD to use gradients.""" 151f8bc67e5Sjeremylt 152f8bc67e5Sjeremylt # libCEED call 153f8bc67e5Sjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 154477729cfSJeremy L Thompson err_code = lib.CeedQFunctionAddOutput( 1557a7b0fa3SJed Brown self._pointer[0], fieldnameAscii, size, emode) 156477729cfSJeremy L Thompson self._ceed._check_error(err_code) 157f8bc67e5Sjeremylt 158f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 1597a7b0fa3SJed Brown 1607a7b0fa3SJed Brown 161f8bc67e5Sjeremyltclass QFunctionByName(_QFunctionBase): 162f8bc67e5Sjeremylt """Ceed QFunction By Name: point-wise operation at quadrature points 163f8bc67e5Sjeremylt from a given gallery, for evaluating volumetric terms.""" 164f8bc67e5Sjeremylt 165f8bc67e5Sjeremylt # Constructor 166f8bc67e5Sjeremylt def __init__(self, ceed, name): 167f8bc67e5Sjeremylt # libCEED object 168f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 169f8bc67e5Sjeremylt 170f8bc67e5Sjeremylt # Reference to Ceed 171f8bc67e5Sjeremylt self._ceed = ceed 172f8bc67e5Sjeremylt 173f8bc67e5Sjeremylt # libCEED call 174f8bc67e5Sjeremylt nameAscii = ffi.new("char[]", name.encode('ascii')) 175477729cfSJeremy L Thompson err_code = lib.CeedQFunctionCreateInteriorByName(self._ceed._pointer[0], 176477729cfSJeremy L Thompson nameAscii, self._pointer) 177477729cfSJeremy L Thompson self._ceed._check_error(err_code) 178f8bc67e5Sjeremylt 179f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 1807a7b0fa3SJed Brown 1817a7b0fa3SJed Brown 182f8bc67e5Sjeremyltclass IdentityQFunction(_QFunctionBase): 183f8bc67e5Sjeremylt """Ceed Identity QFunction: identity qfunction operation.""" 184f8bc67e5Sjeremylt 185f8bc67e5Sjeremylt # Constructor 186f8bc67e5Sjeremylt def __init__(self, ceed, size, inmode, outmode): 187f8bc67e5Sjeremylt # libCEED object 188f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 189f8bc67e5Sjeremylt 190f8bc67e5Sjeremylt # Reference to Ceed 191f8bc67e5Sjeremylt self._ceed = ceed 192f8bc67e5Sjeremylt 193f8bc67e5Sjeremylt # libCEED call 194477729cfSJeremy L Thompson err_code = lib.CeedQFunctionCreateIdentity(self._ceed._pointer[0], size, 195477729cfSJeremy L Thompson inmode, outmode, self._pointer) 196f8bc67e5Sjeremylt 197f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 198