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 35477729cfSJeremy L Thompson err_code = lib.CeedOperatorDestroy(self._pointer) 36477729cfSJeremy 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 51477729cfSJeremy L Thompson err_code = lib.CeedOperatorView(self._pointer[0], stream) 52477729cfSJeremy 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 68477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleDiagonal(self._pointer[0], 696397b31bSJeremy L Thompson d._pointer[0], request) 70477729cfSJeremy 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 81477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleAddDiagonal(self._pointer[0], 826397b31bSJeremy L Thompson d._pointer[0], request) 83477729cfSJeremy 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 97477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssemblePointBlockDiagonal(self._pointer[0], 986397b31bSJeremy L Thompson d._pointer[0], request) 99477729cfSJeremy 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 113477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleAddPointBlockDiagonal(self._pointer[0], 1146397b31bSJeremy L Thompson d._pointer[0], request) 115477729cfSJeremy 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 129477729cfSJeremy L Thompson err_code = lib.CeedOperatorApply(self._pointer[0], u._pointer[0], v._pointer[0], 130f2d2bf5dSjeremylt request) 131477729cfSJeremy 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 145477729cfSJeremy L Thompson err_code = lib.CeedOperatorApplyAdd(self._pointer[0], u._pointer[0], v._pointer[0], 146f2d2bf5dSjeremylt request) 147477729cfSJeremy L Thompson self._ceed._check_error(err_code) 148f2d2bf5dSjeremylt 149*d99fa3c5SJeremy L Thompson # Create Multigrid Level 150*d99fa3c5SJeremy L Thompson def multigrid_create(self, p_mult_fine, rstr_coarse, basis_coarse): 151*d99fa3c5SJeremy L Thompson """ Create a multigrid coarse operator and level transfer operators 152*d99fa3c5SJeremy L Thompson for a CeedOperator with a Lagrange tensor basis for the active basis 153*d99fa3c5SJeremy L Thompson 154*d99fa3c5SJeremy L Thompson Args: 155*d99fa3c5SJeremy L Thompson p_mult_fine: L-vector multiplicity in parallel gather/scatter 156*d99fa3c5SJeremy L Thompson basis_coarse: Coarse grid active vector basis 157*d99fa3c5SJeremy L Thompson degree_coarse: Coarse grid basis polynomial order""" 158*d99fa3c5SJeremy L Thompson 159*d99fa3c5SJeremy L Thompson # Operator pointers 160*d99fa3c5SJeremy L Thompson opCoarsePointer = ffi.new("CeedOperator *") 161*d99fa3c5SJeremy L Thompson opProlongPointer = ffi.new("CeedOperator *") 162*d99fa3c5SJeremy L Thompson opRestrictPointer = ffi.new("CeedOperator *") 163*d99fa3c5SJeremy L Thompson 164*d99fa3c5SJeremy L Thompson # libCEED call 165*d99fa3c5SJeremy L Thompson lib.CeedOperatorMultigridLevelCreate(self._pointer[0], 166*d99fa3c5SJeremy L Thompson p_mult_fine._pointer[0], 167*d99fa3c5SJeremy L Thompson rstr_coarse._pointer[0], 168*d99fa3c5SJeremy L Thompson basis_coarse._pointer[0], 169*d99fa3c5SJeremy L Thompson opCoarsePointer, 170*d99fa3c5SJeremy L Thompson opProlongPointer, 171*d99fa3c5SJeremy L Thompson opRestrictPointer) 172*d99fa3c5SJeremy L Thompson 173*d99fa3c5SJeremy L Thompson # Wrap operators 174*d99fa3c5SJeremy L Thompson opCoarse = _OperatorWrap( 175*d99fa3c5SJeremy L Thompson self._ceed, opCoarsePointer) 176*d99fa3c5SJeremy L Thompson opProlong = _OperatorWrap( 177*d99fa3c5SJeremy L Thompson self._ceed, opProlongPointer) 178*d99fa3c5SJeremy L Thompson opRestrict = _OperatorWrap( 179*d99fa3c5SJeremy L Thompson self._ceed, opRestrictPointer) 180*d99fa3c5SJeremy L Thompson 181*d99fa3c5SJeremy L Thompson # Return 182*d99fa3c5SJeremy L Thompson return [opCoarse, opProlong, opRestrict] 183*d99fa3c5SJeremy L Thompson 184*d99fa3c5SJeremy L Thompson # Create Multigrid Level 185*d99fa3c5SJeremy L Thompson def multigrid_create_tensor_h1(self, p_mult_fine, rstr_coarse, basis_coarse, 186*d99fa3c5SJeremy L Thompson interp_C_to_F): 187*d99fa3c5SJeremy L Thompson """ Create a multigrid coarse operator and level transfer operators 188*d99fa3c5SJeremy L Thompson for a CeedOperator with a non-tensor basis for the active basis 189*d99fa3c5SJeremy L Thompson 190*d99fa3c5SJeremy L Thompson Args: 191*d99fa3c5SJeremy L Thompson p_mult_fine: L-vector multiplicity in parallel gather/scatter 192*d99fa3c5SJeremy L Thompson rstr_coarse: Coarse grid restriction 193*d99fa3c5SJeremy L Thompson basis_coarse: Coarse grid active vector basis 194*d99fa3c5SJeremy L Thompson interp_C_to_F: Matrix for coarse to fine interpolation""" 195*d99fa3c5SJeremy L Thompson 196*d99fa3c5SJeremy L Thompson # Setup arguments 197*d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.new("CeedScalar *") 198*d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.cast( 199*d99fa3c5SJeremy L Thompson "CeedScalar *", 200*d99fa3c5SJeremy L Thompson interp_C_to_F.__array_interface__['data'][0]) 201*d99fa3c5SJeremy L Thompson 202*d99fa3c5SJeremy L Thompson # Operator pointers 203*d99fa3c5SJeremy L Thompson opCoarsePointer = ffi.new("CeedOperator *") 204*d99fa3c5SJeremy L Thompson opProlongPointer = ffi.new("CeedOperator *") 205*d99fa3c5SJeremy L Thompson opRestrictPointer = ffi.new("CeedOperator *") 206*d99fa3c5SJeremy L Thompson 207*d99fa3c5SJeremy L Thompson # libCEED call 208*d99fa3c5SJeremy L Thompson lib.CeedOperatorMultigridLevelCreateTensorH1(self._pointer[0], 209*d99fa3c5SJeremy L Thompson p_mult_fine._pointer[0], 210*d99fa3c5SJeremy L Thompson rstr_coarse._pointer[0], 211*d99fa3c5SJeremy L Thompson basis_coarse._pointer[0], 212*d99fa3c5SJeremy L Thompson interpCtoF_pointer, 213*d99fa3c5SJeremy L Thompson opCoarsePointer, 214*d99fa3c5SJeremy L Thompson opProlongPointer, 215*d99fa3c5SJeremy L Thompson opRestrictPointer) 216*d99fa3c5SJeremy L Thompson 217*d99fa3c5SJeremy L Thompson # Wrap operators 218*d99fa3c5SJeremy L Thompson opCoarse = _OperatorWrap( 219*d99fa3c5SJeremy L Thompson self._ceed, opCoarsePointer) 220*d99fa3c5SJeremy L Thompson opProlong = _OperatorWrap( 221*d99fa3c5SJeremy L Thompson self._ceed, opProlongPointer) 222*d99fa3c5SJeremy L Thompson opRestrict = _OperatorWrap( 223*d99fa3c5SJeremy L Thompson self._ceed, opRestrictPointer) 224*d99fa3c5SJeremy L Thompson 225*d99fa3c5SJeremy L Thompson # Return 226*d99fa3c5SJeremy L Thompson return [opCoarse, opProlong, opRestrict] 227*d99fa3c5SJeremy L Thompson 228*d99fa3c5SJeremy L Thompson # Create Multigrid Level 229*d99fa3c5SJeremy L Thompson def multigrid_create_h1(self, p_mult_fine, rstr_coarse, basis_coarse, 230*d99fa3c5SJeremy L Thompson interp_C_to_F): 231*d99fa3c5SJeremy L Thompson """ Create a multigrid coarse operator and level transfer operators 232*d99fa3c5SJeremy L Thompson for a CeedOperator with a Lagrange tensor basis for the active basis 233*d99fa3c5SJeremy L Thompson 234*d99fa3c5SJeremy L Thompson Args: 235*d99fa3c5SJeremy L Thompson p_mult_fine: L-vector multiplicity in parallel gather/scatter 236*d99fa3c5SJeremy L Thompson rstr_coarse: Coarse grid restriction 237*d99fa3c5SJeremy L Thompson basis_coarse: Coarse grid active vector basis 238*d99fa3c5SJeremy L Thompson interp_C_to_F: Matrix for coarse to fine interpolation""" 239*d99fa3c5SJeremy L Thompson 240*d99fa3c5SJeremy L Thompson # Setup arguments 241*d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.new("CeedScalar *") 242*d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.cast( 243*d99fa3c5SJeremy L Thompson "CeedScalar *", 244*d99fa3c5SJeremy L Thompson interp_C_to_F.__array_interface__['data'][0]) 245*d99fa3c5SJeremy L Thompson 246*d99fa3c5SJeremy L Thompson # Operator pointers 247*d99fa3c5SJeremy L Thompson opCoarsePointer = ffi.new("CeedOperator *") 248*d99fa3c5SJeremy L Thompson opProlongPointer = ffi.new("CeedOperator *") 249*d99fa3c5SJeremy L Thompson opRestrictPointer = ffi.new("CeedOperator *") 250*d99fa3c5SJeremy L Thompson 251*d99fa3c5SJeremy L Thompson # libCEED call 252*d99fa3c5SJeremy L Thompson lib.CeedOperatorMultigridLevelCreateH1(self._pointer[0], 253*d99fa3c5SJeremy L Thompson p_mult_fine._pointer[0], 254*d99fa3c5SJeremy L Thompson rstr_coarse._pointer[0], 255*d99fa3c5SJeremy L Thompson basis_coarse._pointer[0], 256*d99fa3c5SJeremy L Thompson interpCtoF_pointer, 257*d99fa3c5SJeremy L Thompson opCoarsePointer, 258*d99fa3c5SJeremy L Thompson opProlongPointer, 259*d99fa3c5SJeremy L Thompson opRestrictPointer) 260*d99fa3c5SJeremy L Thompson 261*d99fa3c5SJeremy L Thompson # Wrap operators 262*d99fa3c5SJeremy L Thompson opCoarse = _OperatorWrap( 263*d99fa3c5SJeremy L Thompson self._ceed, opCoarsePointer) 264*d99fa3c5SJeremy L Thompson opProlong = _OperatorWrap( 265*d99fa3c5SJeremy L Thompson self._ceed, opProlongPointer) 266*d99fa3c5SJeremy L Thompson opRestrict = _OperatorWrap( 267*d99fa3c5SJeremy L Thompson self._ceed, opRestrictPointer) 268*d99fa3c5SJeremy L Thompson 269*d99fa3c5SJeremy L Thompson # Return 270*d99fa3c5SJeremy L Thompson return [opCoarse, opProlong, opRestrict] 271*d99fa3c5SJeremy L Thompson 272*d99fa3c5SJeremy L Thompson 273f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 2747a7b0fa3SJed Brown 2757a7b0fa3SJed Brown 276f2d2bf5dSjeremyltclass Operator(_OperatorBase): 277f2d2bf5dSjeremylt """Ceed Operator: composed FE-type operations on vectors.""" 278f2d2bf5dSjeremylt 279f2d2bf5dSjeremylt # Constructor 280f2d2bf5dSjeremylt def __init__(self, ceed, qf, dqf=None, dqfT=None): 281f2d2bf5dSjeremylt # CeedOperator object 282f2d2bf5dSjeremylt self._pointer = ffi.new("CeedOperator *") 283f2d2bf5dSjeremylt 284f2d2bf5dSjeremylt # Reference to Ceed 285f2d2bf5dSjeremylt self._ceed = ceed 286f2d2bf5dSjeremylt 287f2d2bf5dSjeremylt # libCEED call 288477729cfSJeremy L Thompson err_code = lib.CeedOperatorCreate(self._ceed._pointer[0], qf._pointer[0], 289f2d2bf5dSjeremylt dqf._pointer[0] if dqf else ffi.NULL, 290f2d2bf5dSjeremylt dqfT._pointer[0] if dqfT else ffi.NULL, 291f2d2bf5dSjeremylt self._pointer) 292477729cfSJeremy L Thompson self._ceed._check_error(err_code) 293f2d2bf5dSjeremylt 294f2d2bf5dSjeremylt # Add field to CeedOperator 295a8d32208Sjeremylt def set_field(self, fieldname, restriction, basis, vector): 296f2d2bf5dSjeremylt """Provide a field to an Operator for use by its QFunction. 297f2d2bf5dSjeremylt 298f2d2bf5dSjeremylt Args: 299f2d2bf5dSjeremylt fieldname: name of the field (to be matched with the same name used 300f2d2bf5dSjeremylt by QFunction) 301f2d2bf5dSjeremylt restriction: ElemRestriction 302f2d2bf5dSjeremylt basis: Basis in which the field resides or CEED_BASIS_COLLOCATED 303f2d2bf5dSjeremylt if collocated with quadrature points 304f2d2bf5dSjeremylt vector: Vector to be used by Operator or CEED_VECTOR_ACTIVE 305f2d2bf5dSjeremylt if field is active or CEED_VECTOR_NONE if using 306a8d32208Sjeremylt CEED_EVAL_WEIGHT in the QFunction""" 307f2d2bf5dSjeremylt 308f2d2bf5dSjeremylt # libCEED call 309f2d2bf5dSjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 310477729cfSJeremy L Thompson err_code = lib.CeedOperatorSetField(self._pointer[0], fieldnameAscii, 311a8d32208Sjeremylt restriction._pointer[0], basis._pointer[0], 312f2d2bf5dSjeremylt vector._pointer[0]) 313477729cfSJeremy L Thompson self._ceed._check_error(err_code) 314f2d2bf5dSjeremylt 315f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 3167a7b0fa3SJed Brown 3177a7b0fa3SJed Brown 318f2d2bf5dSjeremyltclass CompositeOperator(_OperatorBase): 319f2d2bf5dSjeremylt """Ceed Composite Operator: composition of multiple Operators.""" 320f2d2bf5dSjeremylt 321f2d2bf5dSjeremylt # Constructor 322f2d2bf5dSjeremylt def __init__(self, ceed): 323f2d2bf5dSjeremylt # CeedOperator object 324f2d2bf5dSjeremylt self._pointer = ffi.new("CeedOperator *") 325f2d2bf5dSjeremylt 326f2d2bf5dSjeremylt # Reference to Ceed 327f2d2bf5dSjeremylt self._ceed = ceed 328f2d2bf5dSjeremylt # libCEED call 329477729cfSJeremy L Thompson err_code = lib.CeedCompositeOperatorCreate( 330477729cfSJeremy L Thompson self._ceed._pointer[0], self._pointer) 331477729cfSJeremy L Thompson self._ceed._check_error(err_code) 332f2d2bf5dSjeremylt 333f2d2bf5dSjeremylt # Add sub operators 334f2d2bf5dSjeremylt def add_sub(self, subop): 335f2d2bf5dSjeremylt """Add a sub-operator to a composite CeedOperator. 336f2d2bf5dSjeremylt 337f2d2bf5dSjeremylt Args: 338f2d2bf5dSjeremylt subop: sub-operator Operator""" 339f2d2bf5dSjeremylt 340f2d2bf5dSjeremylt # libCEED call 341477729cfSJeremy L Thompson err_code = lib.CeedCompositeOperatorAddSub( 342477729cfSJeremy L Thompson self._pointer[0], subop._pointer[0]) 343477729cfSJeremy L Thompson self._ceed._check_error(err_code) 344f2d2bf5dSjeremylt 345f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 346*d99fa3c5SJeremy L Thompson 347*d99fa3c5SJeremy L Thompson 348*d99fa3c5SJeremy L Thompsonclass _OperatorWrap(Operator): 349*d99fa3c5SJeremy L Thompson """Wrap a CeedOperator pointer in a Operator object.""" 350*d99fa3c5SJeremy L Thompson 351*d99fa3c5SJeremy L Thompson # Constructor 352*d99fa3c5SJeremy L Thompson def __init__(self, ceed, pointer): 353*d99fa3c5SJeremy L Thompson # CeedOperator object 354*d99fa3c5SJeremy L Thompson self._pointer = pointer 355*d99fa3c5SJeremy L Thompson 356*d99fa3c5SJeremy L Thompson # Reference to Ceed 357*d99fa3c5SJeremy L Thompson self._ceed = ceed 358*d99fa3c5SJeremy L Thompson 359*d99fa3c5SJeremy L Thompson# ------------------------------------------------------------------------------ 360