1f2d2bf5dSjeremylt# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2f2d2bf5dSjeremylt# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3f2d2bf5dSjeremylt# reserved. See files LICENSE and NOTICE for details. 4f2d2bf5dSjeremylt# 5f2d2bf5dSjeremylt# This file is part of CEED, a collection of benchmarks, miniapps, software 6f2d2bf5dSjeremylt# libraries and APIs for efficient high-order finite element and spectral 7f2d2bf5dSjeremylt# element discretizations for exascale applications. For more information and 8f2d2bf5dSjeremylt# source code availability see http://github.com/ceed. 9f2d2bf5dSjeremylt# 10f2d2bf5dSjeremylt# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11f2d2bf5dSjeremylt# a collaborative effort of two U.S. Department of Energy organizations (Office 12f2d2bf5dSjeremylt# of Science and the National Nuclear Security Administration) responsible for 13f2d2bf5dSjeremylt# the planning and preparation of a capable exascale ecosystem, including 14f2d2bf5dSjeremylt# software, applications, hardware, advanced system engineering and early 15f2d2bf5dSjeremylt# testbed platforms, in support of the nation's exascale computing imperative. 16f2d2bf5dSjeremylt 17f2d2bf5dSjeremyltfrom _ceed_cffi import ffi, lib 18f2d2bf5dSjeremyltimport tempfile 19f2d2bf5dSjeremyltfrom abc import ABC 20f2d2bf5dSjeremyltfrom .ceed_constants import REQUEST_IMMEDIATE, REQUEST_ORDERED, NOTRANSPOSE 21f2d2bf5dSjeremylt 22f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 237a7b0fa3SJed Brown 247a7b0fa3SJed Brown 25f2d2bf5dSjeremyltclass _OperatorBase(ABC): 26f2d2bf5dSjeremylt """Ceed Operator: composed FE-type operations on vectors.""" 27f2d2bf5dSjeremylt 28f2d2bf5dSjeremylt # Attributes 29f2d2bf5dSjeremylt _ceed = ffi.NULL 30f2d2bf5dSjeremylt _pointer = ffi.NULL 31f2d2bf5dSjeremylt 32f2d2bf5dSjeremylt # Destructor 33f2d2bf5dSjeremylt def __del__(self): 34f2d2bf5dSjeremylt # libCEED call 35*477729cfSJeremy L Thompson err_code = lib.CeedOperatorDestroy(self._pointer) 36*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 37f2d2bf5dSjeremylt 38f2d2bf5dSjeremylt # Representation 39f2d2bf5dSjeremylt def __repr__(self): 40f2d2bf5dSjeremylt return "<CeedOperator instance at " + hex(id(self)) + ">" 41f2d2bf5dSjeremylt 42f2d2bf5dSjeremylt # String conversion for print() to stdout 43f2d2bf5dSjeremylt def __str__(self): 44f2d2bf5dSjeremylt """View an Operator via print().""" 45f2d2bf5dSjeremylt 46f2d2bf5dSjeremylt # libCEED call 47f2d2bf5dSjeremylt with tempfile.NamedTemporaryFile() as key_file: 48f2d2bf5dSjeremylt with open(key_file.name, 'r+') as stream_file: 49f2d2bf5dSjeremylt stream = ffi.cast("FILE *", stream_file) 50f2d2bf5dSjeremylt 51*477729cfSJeremy L Thompson err_code = lib.CeedOperatorView(self._pointer[0], stream) 52*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 53f2d2bf5dSjeremylt 54f2d2bf5dSjeremylt stream_file.seek(0) 55f2d2bf5dSjeremylt out_string = stream_file.read() 56f2d2bf5dSjeremylt 57f2d2bf5dSjeremylt return out_string 58f2d2bf5dSjeremylt 596397b31bSJeremy L Thompson # Assemble linear diagonal 606397b31bSJeremy L Thompson def linear_assemble_diagonal(self, d, request=REQUEST_IMMEDIATE): 616397b31bSJeremy L Thompson """Assemble the diagonal of a square linear Operator 626397b31bSJeremy L Thompson 636397b31bSJeremy L Thompson Args: 646397b31bSJeremy L Thompson d: Vector to store assembled Operator diagonal 656397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 666397b31bSJeremy L Thompson 676397b31bSJeremy L Thompson # libCEED call 68*477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleDiagonal(self._pointer[0], 696397b31bSJeremy L Thompson d._pointer[0], request) 70*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 716397b31bSJeremy L Thompson 726397b31bSJeremy L Thompson # Assemble add linear diagonal 736397b31bSJeremy L Thompson def linear_assemble_add_diagonal(self, d, request=REQUEST_IMMEDIATE): 746397b31bSJeremy L Thompson """Sum the diagonal of a square linear Operator into a Vector 756397b31bSJeremy L Thompson 766397b31bSJeremy L Thompson Args: 776397b31bSJeremy L Thompson d: Vector to store assembled Operator diagonal 786397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 796397b31bSJeremy L Thompson 806397b31bSJeremy L Thompson # libCEED call 81*477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleAddDiagonal(self._pointer[0], 826397b31bSJeremy L Thompson d._pointer[0], request) 83*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 846397b31bSJeremy L Thompson 856397b31bSJeremy L Thompson # Assemble linear point block diagonal 860c9255dfSJeremy L Thompson def linear_assemble_point_block_diagonal( 870c9255dfSJeremy L Thompson self, d, request=REQUEST_IMMEDIATE): 880c9255dfSJeremy L Thompson """Assemble the point block diagonal of a square linear Operator 896397b31bSJeremy L Thompson 906397b31bSJeremy L Thompson Args: 916397b31bSJeremy L Thompson d: Vector to store assembled Operator point block diagonal, 926397b31bSJeremy L Thompson provided in row-major form with an ncomp*ncomp block 936397b31bSJeremy L Thompson at each node 946397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 956397b31bSJeremy L Thompson 966397b31bSJeremy L Thompson # libCEED call 97*477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssemblePointBlockDiagonal(self._pointer[0], 986397b31bSJeremy L Thompson d._pointer[0], request) 99*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1006397b31bSJeremy L Thompson 1016397b31bSJeremy L Thompson # Assemble linear point block diagonal 1020c9255dfSJeremy L Thompson def linear_assemble_add_point_block_diagonal( 1030c9255dfSJeremy L Thompson self, d, request=REQUEST_IMMEDIATE): 1040c9255dfSJeremy L Thompson """Sum the point block diagonal of a square linear Operator into a Vector 1056397b31bSJeremy L Thompson 1066397b31bSJeremy L Thompson Args: 1076397b31bSJeremy L Thompson d: Vector to store assembled Operator point block diagonal, 1086397b31bSJeremy L Thompson provided in row-major form with an ncomp*ncomp block 1096397b31bSJeremy L Thompson at each node 1106397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 1116397b31bSJeremy L Thompson 1126397b31bSJeremy L Thompson # libCEED call 113*477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleAddPointBlockDiagonal(self._pointer[0], 1146397b31bSJeremy L Thompson d._pointer[0], request) 115*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1166397b31bSJeremy L Thompson 117f2d2bf5dSjeremylt # Apply CeedOperator 118f2d2bf5dSjeremylt def apply(self, u, v, request=REQUEST_IMMEDIATE): 119f2d2bf5dSjeremylt """Apply Operator to a vector. 120f2d2bf5dSjeremylt 121f2d2bf5dSjeremylt Args: 122f2d2bf5dSjeremylt u: Vector containing input state or CEED_VECTOR_NONE if there are no 123f2d2bf5dSjeremylt active inputs 124f2d2bf5dSjeremylt v: Vector to store result of applying operator (must be distinct from u) 125f2d2bf5dSjeremylt or CEED_VECTOR_NONE if there are no active outputs 126f2d2bf5dSjeremylt **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 127f2d2bf5dSjeremylt 128f2d2bf5dSjeremylt # libCEED call 129*477729cfSJeremy L Thompson err_code = lib.CeedOperatorApply(self._pointer[0], u._pointer[0], v._pointer[0], 130f2d2bf5dSjeremylt request) 131*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 132f2d2bf5dSjeremylt 133f2d2bf5dSjeremylt # Apply CeedOperator 134f2d2bf5dSjeremylt def apply_add(self, u, v, request=REQUEST_IMMEDIATE): 135f2d2bf5dSjeremylt """Apply Operator to a vector and add result to output vector. 136f2d2bf5dSjeremylt 137f2d2bf5dSjeremylt Args: 138f2d2bf5dSjeremylt u: Vector containing input state or CEED_VECTOR_NONE if there are no 139f2d2bf5dSjeremylt active inputs 140f2d2bf5dSjeremylt v: Vector to sum in result of applying operator (must be distinct from u) 141f2d2bf5dSjeremylt or CEED_VECTOR_NONE if there are no active outputs 142f2d2bf5dSjeremylt **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 143f2d2bf5dSjeremylt 144f2d2bf5dSjeremylt # libCEED call 145*477729cfSJeremy L Thompson err_code = lib.CeedOperatorApplyAdd(self._pointer[0], u._pointer[0], v._pointer[0], 146f2d2bf5dSjeremylt request) 147*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 148f2d2bf5dSjeremylt 149f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 1507a7b0fa3SJed Brown 1517a7b0fa3SJed Brown 152f2d2bf5dSjeremyltclass Operator(_OperatorBase): 153f2d2bf5dSjeremylt """Ceed Operator: composed FE-type operations on vectors.""" 154f2d2bf5dSjeremylt 155f2d2bf5dSjeremylt # Constructor 156f2d2bf5dSjeremylt def __init__(self, ceed, qf, dqf=None, dqfT=None): 157f2d2bf5dSjeremylt # CeedOperator object 158f2d2bf5dSjeremylt self._pointer = ffi.new("CeedOperator *") 159f2d2bf5dSjeremylt 160f2d2bf5dSjeremylt # Reference to Ceed 161f2d2bf5dSjeremylt self._ceed = ceed 162f2d2bf5dSjeremylt 163f2d2bf5dSjeremylt # libCEED call 164*477729cfSJeremy L Thompson err_code = lib.CeedOperatorCreate(self._ceed._pointer[0], qf._pointer[0], 165f2d2bf5dSjeremylt dqf._pointer[0] if dqf else ffi.NULL, 166f2d2bf5dSjeremylt dqfT._pointer[0] if dqfT else ffi.NULL, 167f2d2bf5dSjeremylt self._pointer) 168*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 169f2d2bf5dSjeremylt 170f2d2bf5dSjeremylt # Add field to CeedOperator 171a8d32208Sjeremylt def set_field(self, fieldname, restriction, basis, vector): 172f2d2bf5dSjeremylt """Provide a field to an Operator for use by its QFunction. 173f2d2bf5dSjeremylt 174f2d2bf5dSjeremylt Args: 175f2d2bf5dSjeremylt fieldname: name of the field (to be matched with the same name used 176f2d2bf5dSjeremylt by QFunction) 177f2d2bf5dSjeremylt restriction: ElemRestriction 178f2d2bf5dSjeremylt basis: Basis in which the field resides or CEED_BASIS_COLLOCATED 179f2d2bf5dSjeremylt if collocated with quadrature points 180f2d2bf5dSjeremylt vector: Vector to be used by Operator or CEED_VECTOR_ACTIVE 181f2d2bf5dSjeremylt if field is active or CEED_VECTOR_NONE if using 182a8d32208Sjeremylt CEED_EVAL_WEIGHT in the QFunction""" 183f2d2bf5dSjeremylt 184f2d2bf5dSjeremylt # libCEED call 185f2d2bf5dSjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 186*477729cfSJeremy L Thompson err_code = lib.CeedOperatorSetField(self._pointer[0], fieldnameAscii, 187a8d32208Sjeremylt restriction._pointer[0], basis._pointer[0], 188f2d2bf5dSjeremylt vector._pointer[0]) 189*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 190f2d2bf5dSjeremylt 191f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 1927a7b0fa3SJed Brown 1937a7b0fa3SJed Brown 194f2d2bf5dSjeremyltclass CompositeOperator(_OperatorBase): 195f2d2bf5dSjeremylt """Ceed Composite Operator: composition of multiple Operators.""" 196f2d2bf5dSjeremylt 197f2d2bf5dSjeremylt # Constructor 198f2d2bf5dSjeremylt def __init__(self, ceed): 199f2d2bf5dSjeremylt # CeedOperator object 200f2d2bf5dSjeremylt self._pointer = ffi.new("CeedOperator *") 201f2d2bf5dSjeremylt 202f2d2bf5dSjeremylt # Reference to Ceed 203f2d2bf5dSjeremylt self._ceed = ceed 204f2d2bf5dSjeremylt # libCEED call 205*477729cfSJeremy L Thompson err_code = lib.CeedCompositeOperatorCreate( 206*477729cfSJeremy L Thompson self._ceed._pointer[0], self._pointer) 207*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 208f2d2bf5dSjeremylt 209f2d2bf5dSjeremylt # Add sub operators 210f2d2bf5dSjeremylt def add_sub(self, subop): 211f2d2bf5dSjeremylt """Add a sub-operator to a composite CeedOperator. 212f2d2bf5dSjeremylt 213f2d2bf5dSjeremylt Args: 214f2d2bf5dSjeremylt subop: sub-operator Operator""" 215f2d2bf5dSjeremylt 216f2d2bf5dSjeremylt # libCEED call 217*477729cfSJeremy L Thompson err_code = lib.CeedCompositeOperatorAddSub( 218*477729cfSJeremy L Thompson self._pointer[0], subop._pointer[0]) 219*477729cfSJeremy L Thompson self._ceed._check_error(err_code) 220f2d2bf5dSjeremylt 221f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 222