1*3d8e8822SJeremy L Thompson# Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors 2*3d8e8822SJeremy L Thompson# All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3f8bc67e5Sjeremylt# 4*3d8e8822SJeremy L Thompson# SPDX-License-Identifier: BSD-2-Clause 5f8bc67e5Sjeremylt# 6*3d8e8822SJeremy L Thompson# This file is part of CEED: http://github.com/ceed 7f8bc67e5Sjeremylt 8f8bc67e5Sjeremyltfrom _ceed_cffi import ffi, lib 9f8bc67e5Sjeremyltimport ctypes 10f8bc67e5Sjeremyltimport tempfile 11f8bc67e5Sjeremyltfrom abc import ABC 12f8bc67e5Sjeremylt 13f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 147a7b0fa3SJed Brown 157a7b0fa3SJed Brown 16f8bc67e5Sjeremyltclass _QFunctionBase(ABC): 17f8bc67e5Sjeremylt """Ceed QFunction: point-wise operation at quadrature points for evaluating 18f8bc67e5Sjeremylt volumetric terms.""" 19f8bc67e5Sjeremylt 20f8bc67e5Sjeremylt # Destructor 21f8bc67e5Sjeremylt def __del__(self): 22f8bc67e5Sjeremylt # libCEED call 23477729cfSJeremy L Thompson err_code = lib.CeedQFunctionDestroy(self._pointer) 24477729cfSJeremy L Thompson self._ceed._check_error(err_code) 25f8bc67e5Sjeremylt 26f8bc67e5Sjeremylt # Representation 27f8bc67e5Sjeremylt def __repr__(self): 28f8bc67e5Sjeremylt return "<CeedQFunction instance at " + hex(id(self)) + ">" 29f8bc67e5Sjeremylt 30f8bc67e5Sjeremylt # String conversion for print() to stdout 31f8bc67e5Sjeremylt def __str__(self): 32f8bc67e5Sjeremylt """View a QFunction via print().""" 33f8bc67e5Sjeremylt 34f8bc67e5Sjeremylt # libCEED call 35f8bc67e5Sjeremylt with tempfile.NamedTemporaryFile() as key_file: 36f8bc67e5Sjeremylt with open(key_file.name, 'r+') as stream_file: 37f8bc67e5Sjeremylt stream = ffi.cast("FILE *", stream_file) 38f8bc67e5Sjeremylt 39477729cfSJeremy L Thompson err_code = lib.CeedQFunctionView(self._pointer[0], stream) 40477729cfSJeremy L Thompson self._ceed._check_error(err_code) 41f8bc67e5Sjeremylt 42f8bc67e5Sjeremylt stream_file.seek(0) 43f8bc67e5Sjeremylt out_string = stream_file.read() 44f8bc67e5Sjeremylt 45f8bc67e5Sjeremylt return out_string 46f8bc67e5Sjeremylt 47f8bc67e5Sjeremylt # Apply CeedQFunction 48f8bc67e5Sjeremylt def apply(self, q, inputs, outputs): 49f8bc67e5Sjeremylt """Apply the action of a QFunction. 50f8bc67e5Sjeremylt 51f8bc67e5Sjeremylt Args: 52f8bc67e5Sjeremylt q: number of quadrature points 53f8bc67e5Sjeremylt *inputs: array of input data vectors 54f8bc67e5Sjeremylt *outputs: array of output data vectors""" 55f8bc67e5Sjeremylt 56f8bc67e5Sjeremylt # Array of vectors 57f8bc67e5Sjeremylt invecs = ffi.new("CeedVector[16]") 58f8bc67e5Sjeremylt for i in range(min(16, len(inputs))): 59f8bc67e5Sjeremylt invecs[i] = inputs[i]._pointer[0] 60f8bc67e5Sjeremylt outvecs = ffi.new("CeedVector[16]") 61f8bc67e5Sjeremylt for i in range(min(16, len(outputs))): 62f8bc67e5Sjeremylt outvecs[i] = outputs[i]._pointer[0] 63f8bc67e5Sjeremylt 64f8bc67e5Sjeremylt # libCEED call 65477729cfSJeremy L Thompson err_code = lib.CeedQFunctionApply(self._pointer[0], q, invecs, outvecs) 66477729cfSJeremy L Thompson self._ceed._check_error(err_code) 67f8bc67e5Sjeremylt 68f8bc67e5Sjeremylt # Clean-up 69f8bc67e5Sjeremylt ffi.release(invecs) 70f8bc67e5Sjeremylt ffi.release(outvecs) 71f8bc67e5Sjeremylt 72f8bc67e5Sjeremylt 73f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 74f8bc67e5Sjeremyltclass QFunction(_QFunctionBase): 75f8bc67e5Sjeremylt """Ceed QFunction: point-wise operation at quadrature points for evaluating 76f8bc67e5Sjeremylt volumetric terms.""" 77f8bc67e5Sjeremylt 78f8bc67e5Sjeremylt # Constructor 79f8bc67e5Sjeremylt def __init__(self, ceed, vlength, f, source): 80f8bc67e5Sjeremylt # libCEED object 81f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 82f8bc67e5Sjeremylt 83f8bc67e5Sjeremylt # Reference to Ceed 84f8bc67e5Sjeremylt self._ceed = ceed 85f8bc67e5Sjeremylt 86f8bc67e5Sjeremylt # Function pointer 877a7b0fa3SJed Brown fpointer = ffi.cast( 887a7b0fa3SJed Brown "CeedQFunctionUser", ctypes.cast( 897a7b0fa3SJed Brown f, ctypes.c_void_p).value) 90f8bc67e5Sjeremylt 91f8bc67e5Sjeremylt # libCEED call 92f8bc67e5Sjeremylt sourceAscii = ffi.new("char[]", source.encode('ascii')) 93477729cfSJeremy L Thompson err_code = lib.CeedQFunctionCreateInterior(self._ceed._pointer[0], vlength, 94477729cfSJeremy L Thompson fpointer, sourceAscii, self._pointer) 95477729cfSJeremy L Thompson self._ceed._check_error(err_code) 96f8bc67e5Sjeremylt 97f8bc67e5Sjeremylt # Set context data 98f8bc67e5Sjeremylt def set_context(self, ctx): 99f8bc67e5Sjeremylt """Set global context for a QFunction. 100f8bc67e5Sjeremylt 101f8bc67e5Sjeremylt Args: 102777ff853SJeremy L Thompson ctx: Ceed User Context object holding context data""" 103f8bc67e5Sjeremylt 104f8bc67e5Sjeremylt # libCEED call 105477729cfSJeremy L Thompson err_code = lib.CeedQFunctionSetContext( 106777ff853SJeremy L Thompson self._pointer[0], 107777ff853SJeremy L Thompson ctx._pointer[0]) 108477729cfSJeremy L Thompson self._ceed._check_error(err_code) 109f8bc67e5Sjeremylt 110f8bc67e5Sjeremylt # Add fields to CeedQFunction 111f8bc67e5Sjeremylt def add_input(self, fieldname, size, emode): 112f8bc67e5Sjeremylt """Add a QFunction input. 113f8bc67e5Sjeremylt 114f8bc67e5Sjeremylt Args: 115f8bc67e5Sjeremylt fieldname: name of QFunction field 116f8bc67e5Sjeremylt size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 117f8bc67e5Sjeremylt (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP 118f8bc67e5Sjeremylt **emode: CEED_EVAL_NONE to use values directly, 119f8bc67e5Sjeremylt CEED_EVAL_INTERP to use interpolated values, 120f8bc67e5Sjeremylt CEED_EVAL_GRAD to use gradients.""" 121f8bc67e5Sjeremylt 122f8bc67e5Sjeremylt # libCEED call 123f8bc67e5Sjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 124477729cfSJeremy L Thompson err_code = lib.CeedQFunctionAddInput( 125450bb777Svaleriabarra self._pointer[0], fieldnameAscii, size, emode) 126477729cfSJeremy L Thompson self._ceed._check_error(err_code) 127f8bc67e5Sjeremylt 128f8bc67e5Sjeremylt def add_output(self, fieldname, size, emode): 129f8bc67e5Sjeremylt """Add a QFunction output. 130f8bc67e5Sjeremylt 131f8bc67e5Sjeremylt Args: 132f8bc67e5Sjeremylt fieldname: name of QFunction field 133f8bc67e5Sjeremylt size: size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 134f8bc67e5Sjeremylt (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP 135f8bc67e5Sjeremylt **emode: CEED_EVAL_NONE to use values directly, 136f8bc67e5Sjeremylt CEED_EVAL_INTERP to use interpolated values, 137f8bc67e5Sjeremylt CEED_EVAL_GRAD to use gradients.""" 138f8bc67e5Sjeremylt 139f8bc67e5Sjeremylt # libCEED call 140f8bc67e5Sjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 141477729cfSJeremy L Thompson err_code = lib.CeedQFunctionAddOutput( 1427a7b0fa3SJed Brown self._pointer[0], fieldnameAscii, size, emode) 143477729cfSJeremy L Thompson self._ceed._check_error(err_code) 144f8bc67e5Sjeremylt 145f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 1467a7b0fa3SJed Brown 1477a7b0fa3SJed Brown 148f8bc67e5Sjeremyltclass QFunctionByName(_QFunctionBase): 149f8bc67e5Sjeremylt """Ceed QFunction By Name: point-wise operation at quadrature points 150f8bc67e5Sjeremylt from a given gallery, for evaluating volumetric terms.""" 151f8bc67e5Sjeremylt 152f8bc67e5Sjeremylt # Constructor 153f8bc67e5Sjeremylt def __init__(self, ceed, name): 154f8bc67e5Sjeremylt # libCEED object 155f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 156f8bc67e5Sjeremylt 157f8bc67e5Sjeremylt # Reference to Ceed 158f8bc67e5Sjeremylt self._ceed = ceed 159f8bc67e5Sjeremylt 160f8bc67e5Sjeremylt # libCEED call 161f8bc67e5Sjeremylt nameAscii = ffi.new("char[]", name.encode('ascii')) 162477729cfSJeremy L Thompson err_code = lib.CeedQFunctionCreateInteriorByName(self._ceed._pointer[0], 163477729cfSJeremy L Thompson nameAscii, self._pointer) 164477729cfSJeremy L Thompson self._ceed._check_error(err_code) 165f8bc67e5Sjeremylt 166f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 1677a7b0fa3SJed Brown 1687a7b0fa3SJed Brown 169f8bc67e5Sjeremyltclass IdentityQFunction(_QFunctionBase): 170f8bc67e5Sjeremylt """Ceed Identity QFunction: identity qfunction operation.""" 171f8bc67e5Sjeremylt 172f8bc67e5Sjeremylt # Constructor 173f8bc67e5Sjeremylt def __init__(self, ceed, size, inmode, outmode): 174f8bc67e5Sjeremylt # libCEED object 175f8bc67e5Sjeremylt self._pointer = ffi.new("CeedQFunction *") 176f8bc67e5Sjeremylt 177f8bc67e5Sjeremylt # Reference to Ceed 178f8bc67e5Sjeremylt self._ceed = ceed 179f8bc67e5Sjeremylt 180f8bc67e5Sjeremylt # libCEED call 181477729cfSJeremy L Thompson err_code = lib.CeedQFunctionCreateIdentity(self._ceed._pointer[0], size, 182477729cfSJeremy L Thompson inmode, outmode, self._pointer) 183f8bc67e5Sjeremylt 184f8bc67e5Sjeremylt# ------------------------------------------------------------------------------ 185