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 # Destructor 29f2d2bf5dSjeremylt def __del__(self): 30f2d2bf5dSjeremylt # libCEED call 31477729cfSJeremy L Thompson err_code = lib.CeedOperatorDestroy(self._pointer) 32477729cfSJeremy L Thompson self._ceed._check_error(err_code) 33f2d2bf5dSjeremylt 34f2d2bf5dSjeremylt # Representation 35f2d2bf5dSjeremylt def __repr__(self): 36f2d2bf5dSjeremylt return "<CeedOperator instance at " + hex(id(self)) + ">" 37f2d2bf5dSjeremylt 38f2d2bf5dSjeremylt # String conversion for print() to stdout 39f2d2bf5dSjeremylt def __str__(self): 40f2d2bf5dSjeremylt """View an Operator via print().""" 41f2d2bf5dSjeremylt 42f2d2bf5dSjeremylt # libCEED call 43f2d2bf5dSjeremylt with tempfile.NamedTemporaryFile() as key_file: 44f2d2bf5dSjeremylt with open(key_file.name, 'r+') as stream_file: 45f2d2bf5dSjeremylt stream = ffi.cast("FILE *", stream_file) 46f2d2bf5dSjeremylt 47477729cfSJeremy L Thompson err_code = lib.CeedOperatorView(self._pointer[0], stream) 48477729cfSJeremy L Thompson self._ceed._check_error(err_code) 49f2d2bf5dSjeremylt 50f2d2bf5dSjeremylt stream_file.seek(0) 51f2d2bf5dSjeremylt out_string = stream_file.read() 52f2d2bf5dSjeremylt 53f2d2bf5dSjeremylt return out_string 54f2d2bf5dSjeremylt 55*28d09c20SJeremy L Thompson # Check Operator setup 56*28d09c20SJeremy L Thompson def check(self): 57*28d09c20SJeremy L Thompson """Check if a CeedOperator is ready to be used""" 58*28d09c20SJeremy L Thompson # libCEED call 59*28d09c20SJeremy L Thompson err_code = lib.CeedOperatorCheckReady(self._pointer[0]) 60*28d09c20SJeremy L Thompson self._ceed._check_error(err_code) 61*28d09c20SJeremy L Thompson 626397b31bSJeremy L Thompson # Assemble linear diagonal 636397b31bSJeremy L Thompson def linear_assemble_diagonal(self, d, request=REQUEST_IMMEDIATE): 646397b31bSJeremy L Thompson """Assemble the diagonal of a square linear Operator 656397b31bSJeremy L Thompson 666397b31bSJeremy L Thompson Args: 676397b31bSJeremy L Thompson d: Vector to store assembled Operator diagonal 686397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 696397b31bSJeremy L Thompson 706397b31bSJeremy L Thompson # libCEED call 71477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleDiagonal(self._pointer[0], 726397b31bSJeremy L Thompson d._pointer[0], request) 73477729cfSJeremy L Thompson self._ceed._check_error(err_code) 746397b31bSJeremy L Thompson 756397b31bSJeremy L Thompson # Assemble add linear diagonal 766397b31bSJeremy L Thompson def linear_assemble_add_diagonal(self, d, request=REQUEST_IMMEDIATE): 776397b31bSJeremy L Thompson """Sum the diagonal of a square linear Operator into a Vector 786397b31bSJeremy L Thompson 796397b31bSJeremy L Thompson Args: 806397b31bSJeremy L Thompson d: Vector to store assembled Operator diagonal 816397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 826397b31bSJeremy L Thompson 836397b31bSJeremy L Thompson # libCEED call 84477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleAddDiagonal(self._pointer[0], 856397b31bSJeremy L Thompson d._pointer[0], request) 86477729cfSJeremy L Thompson self._ceed._check_error(err_code) 876397b31bSJeremy L Thompson 886397b31bSJeremy L Thompson # Assemble linear point block diagonal 890c9255dfSJeremy L Thompson def linear_assemble_point_block_diagonal( 900c9255dfSJeremy L Thompson self, d, request=REQUEST_IMMEDIATE): 910c9255dfSJeremy L Thompson """Assemble the point block diagonal of a square linear Operator 926397b31bSJeremy L Thompson 936397b31bSJeremy L Thompson Args: 946397b31bSJeremy L Thompson d: Vector to store assembled Operator point block diagonal, 956397b31bSJeremy L Thompson provided in row-major form with an ncomp*ncomp block 966397b31bSJeremy L Thompson at each node 976397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 986397b31bSJeremy L Thompson 996397b31bSJeremy L Thompson # libCEED call 100477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssemblePointBlockDiagonal(self._pointer[0], 1016397b31bSJeremy L Thompson d._pointer[0], request) 102477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1036397b31bSJeremy L Thompson 1046397b31bSJeremy L Thompson # Assemble linear point block diagonal 1050c9255dfSJeremy L Thompson def linear_assemble_add_point_block_diagonal( 1060c9255dfSJeremy L Thompson self, d, request=REQUEST_IMMEDIATE): 1070c9255dfSJeremy L Thompson """Sum the point block diagonal of a square linear Operator into a Vector 1086397b31bSJeremy L Thompson 1096397b31bSJeremy L Thompson Args: 1106397b31bSJeremy L Thompson d: Vector to store assembled Operator point block diagonal, 1116397b31bSJeremy L Thompson provided in row-major form with an ncomp*ncomp block 1126397b31bSJeremy L Thompson at each node 1136397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 1146397b31bSJeremy L Thompson 1156397b31bSJeremy L Thompson # libCEED call 116477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleAddPointBlockDiagonal(self._pointer[0], 1176397b31bSJeremy L Thompson d._pointer[0], request) 118477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1196397b31bSJeremy L Thompson 120f2d2bf5dSjeremylt # Apply CeedOperator 121f2d2bf5dSjeremylt def apply(self, u, v, request=REQUEST_IMMEDIATE): 122f2d2bf5dSjeremylt """Apply Operator to a vector. 123f2d2bf5dSjeremylt 124f2d2bf5dSjeremylt Args: 125f2d2bf5dSjeremylt u: Vector containing input state or CEED_VECTOR_NONE if there are no 126f2d2bf5dSjeremylt active inputs 127f2d2bf5dSjeremylt v: Vector to store result of applying operator (must be distinct from u) 128f2d2bf5dSjeremylt or CEED_VECTOR_NONE if there are no active outputs 129f2d2bf5dSjeremylt **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 130f2d2bf5dSjeremylt 131f2d2bf5dSjeremylt # libCEED call 132477729cfSJeremy L Thompson err_code = lib.CeedOperatorApply(self._pointer[0], u._pointer[0], v._pointer[0], 133f2d2bf5dSjeremylt request) 134477729cfSJeremy L Thompson self._ceed._check_error(err_code) 135f2d2bf5dSjeremylt 136f2d2bf5dSjeremylt # Apply CeedOperator 137f2d2bf5dSjeremylt def apply_add(self, u, v, request=REQUEST_IMMEDIATE): 138f2d2bf5dSjeremylt """Apply Operator to a vector and add result to output vector. 139f2d2bf5dSjeremylt 140f2d2bf5dSjeremylt Args: 141f2d2bf5dSjeremylt u: Vector containing input state or CEED_VECTOR_NONE if there are no 142f2d2bf5dSjeremylt active inputs 143f2d2bf5dSjeremylt v: Vector to sum in result of applying operator (must be distinct from u) 144f2d2bf5dSjeremylt or CEED_VECTOR_NONE if there are no active outputs 145f2d2bf5dSjeremylt **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 146f2d2bf5dSjeremylt 147f2d2bf5dSjeremylt # libCEED call 148477729cfSJeremy L Thompson err_code = lib.CeedOperatorApplyAdd(self._pointer[0], u._pointer[0], v._pointer[0], 149f2d2bf5dSjeremylt request) 150477729cfSJeremy L Thompson self._ceed._check_error(err_code) 151f2d2bf5dSjeremylt 152d99fa3c5SJeremy L Thompson # Create Multigrid Level 153d99fa3c5SJeremy L Thompson def multigrid_create(self, p_mult_fine, rstr_coarse, basis_coarse): 154d99fa3c5SJeremy L Thompson """ Create a multigrid coarse operator and level transfer operators 155d99fa3c5SJeremy L Thompson for a CeedOperator with a Lagrange tensor basis for the active basis 156d99fa3c5SJeremy L Thompson 157d99fa3c5SJeremy L Thompson Args: 158d99fa3c5SJeremy L Thompson p_mult_fine: L-vector multiplicity in parallel gather/scatter 159d99fa3c5SJeremy L Thompson basis_coarse: Coarse grid active vector basis 160d99fa3c5SJeremy L Thompson degree_coarse: Coarse grid basis polynomial order""" 161d99fa3c5SJeremy L Thompson 162d99fa3c5SJeremy L Thompson # Operator pointers 163d99fa3c5SJeremy L Thompson opCoarsePointer = ffi.new("CeedOperator *") 164d99fa3c5SJeremy L Thompson opProlongPointer = ffi.new("CeedOperator *") 165d99fa3c5SJeremy L Thompson opRestrictPointer = ffi.new("CeedOperator *") 166d99fa3c5SJeremy L Thompson 167d99fa3c5SJeremy L Thompson # libCEED call 168d99fa3c5SJeremy L Thompson lib.CeedOperatorMultigridLevelCreate(self._pointer[0], 169d99fa3c5SJeremy L Thompson p_mult_fine._pointer[0], 170d99fa3c5SJeremy L Thompson rstr_coarse._pointer[0], 171d99fa3c5SJeremy L Thompson basis_coarse._pointer[0], 172d99fa3c5SJeremy L Thompson opCoarsePointer, 173d99fa3c5SJeremy L Thompson opProlongPointer, 174d99fa3c5SJeremy L Thompson opRestrictPointer) 175d99fa3c5SJeremy L Thompson 176d99fa3c5SJeremy L Thompson # Wrap operators 177d99fa3c5SJeremy L Thompson opCoarse = _OperatorWrap( 178d99fa3c5SJeremy L Thompson self._ceed, opCoarsePointer) 179d99fa3c5SJeremy L Thompson opProlong = _OperatorWrap( 180d99fa3c5SJeremy L Thompson self._ceed, opProlongPointer) 181d99fa3c5SJeremy L Thompson opRestrict = _OperatorWrap( 182d99fa3c5SJeremy L Thompson self._ceed, opRestrictPointer) 183d99fa3c5SJeremy L Thompson 184d99fa3c5SJeremy L Thompson # Return 185d99fa3c5SJeremy L Thompson return [opCoarse, opProlong, opRestrict] 186d99fa3c5SJeremy L Thompson 187d99fa3c5SJeremy L Thompson # Create Multigrid Level 188d99fa3c5SJeremy L Thompson def multigrid_create_tensor_h1(self, p_mult_fine, rstr_coarse, basis_coarse, 189d99fa3c5SJeremy L Thompson interp_C_to_F): 190d99fa3c5SJeremy L Thompson """ Create a multigrid coarse operator and level transfer operators 191d99fa3c5SJeremy L Thompson for a CeedOperator with a non-tensor basis for the active basis 192d99fa3c5SJeremy L Thompson 193d99fa3c5SJeremy L Thompson Args: 194d99fa3c5SJeremy L Thompson p_mult_fine: L-vector multiplicity in parallel gather/scatter 195d99fa3c5SJeremy L Thompson rstr_coarse: Coarse grid restriction 196d99fa3c5SJeremy L Thompson basis_coarse: Coarse grid active vector basis 197d99fa3c5SJeremy L Thompson interp_C_to_F: Matrix for coarse to fine interpolation""" 198d99fa3c5SJeremy L Thompson 199d99fa3c5SJeremy L Thompson # Setup arguments 200d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.new("CeedScalar *") 201d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.cast( 202d99fa3c5SJeremy L Thompson "CeedScalar *", 203d99fa3c5SJeremy L Thompson interp_C_to_F.__array_interface__['data'][0]) 204d99fa3c5SJeremy L Thompson 205d99fa3c5SJeremy L Thompson # Operator pointers 206d99fa3c5SJeremy L Thompson opCoarsePointer = ffi.new("CeedOperator *") 207d99fa3c5SJeremy L Thompson opProlongPointer = ffi.new("CeedOperator *") 208d99fa3c5SJeremy L Thompson opRestrictPointer = ffi.new("CeedOperator *") 209d99fa3c5SJeremy L Thompson 210d99fa3c5SJeremy L Thompson # libCEED call 211d99fa3c5SJeremy L Thompson lib.CeedOperatorMultigridLevelCreateTensorH1(self._pointer[0], 212d99fa3c5SJeremy L Thompson p_mult_fine._pointer[0], 213d99fa3c5SJeremy L Thompson rstr_coarse._pointer[0], 214d99fa3c5SJeremy L Thompson basis_coarse._pointer[0], 215d99fa3c5SJeremy L Thompson interpCtoF_pointer, 216d99fa3c5SJeremy L Thompson opCoarsePointer, 217d99fa3c5SJeremy L Thompson opProlongPointer, 218d99fa3c5SJeremy L Thompson opRestrictPointer) 219d99fa3c5SJeremy L Thompson 220d99fa3c5SJeremy L Thompson # Wrap operators 221d99fa3c5SJeremy L Thompson opCoarse = _OperatorWrap( 222d99fa3c5SJeremy L Thompson self._ceed, opCoarsePointer) 223d99fa3c5SJeremy L Thompson opProlong = _OperatorWrap( 224d99fa3c5SJeremy L Thompson self._ceed, opProlongPointer) 225d99fa3c5SJeremy L Thompson opRestrict = _OperatorWrap( 226d99fa3c5SJeremy L Thompson self._ceed, opRestrictPointer) 227d99fa3c5SJeremy L Thompson 228d99fa3c5SJeremy L Thompson # Return 229d99fa3c5SJeremy L Thompson return [opCoarse, opProlong, opRestrict] 230d99fa3c5SJeremy L Thompson 231d99fa3c5SJeremy L Thompson # Create Multigrid Level 232d99fa3c5SJeremy L Thompson def multigrid_create_h1(self, p_mult_fine, rstr_coarse, basis_coarse, 233d99fa3c5SJeremy L Thompson interp_C_to_F): 234d99fa3c5SJeremy L Thompson """ Create a multigrid coarse operator and level transfer operators 235d99fa3c5SJeremy L Thompson for a CeedOperator with a Lagrange tensor basis for the active basis 236d99fa3c5SJeremy L Thompson 237d99fa3c5SJeremy L Thompson Args: 238d99fa3c5SJeremy L Thompson p_mult_fine: L-vector multiplicity in parallel gather/scatter 239d99fa3c5SJeremy L Thompson rstr_coarse: Coarse grid restriction 240d99fa3c5SJeremy L Thompson basis_coarse: Coarse grid active vector basis 241d99fa3c5SJeremy L Thompson interp_C_to_F: Matrix for coarse to fine interpolation""" 242d99fa3c5SJeremy L Thompson 243d99fa3c5SJeremy L Thompson # Setup arguments 244d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.new("CeedScalar *") 245d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.cast( 246d99fa3c5SJeremy L Thompson "CeedScalar *", 247d99fa3c5SJeremy L Thompson interp_C_to_F.__array_interface__['data'][0]) 248d99fa3c5SJeremy L Thompson 249d99fa3c5SJeremy L Thompson # Operator pointers 250d99fa3c5SJeremy L Thompson opCoarsePointer = ffi.new("CeedOperator *") 251d99fa3c5SJeremy L Thompson opProlongPointer = ffi.new("CeedOperator *") 252d99fa3c5SJeremy L Thompson opRestrictPointer = ffi.new("CeedOperator *") 253d99fa3c5SJeremy L Thompson 254d99fa3c5SJeremy L Thompson # libCEED call 255d99fa3c5SJeremy L Thompson lib.CeedOperatorMultigridLevelCreateH1(self._pointer[0], 256d99fa3c5SJeremy L Thompson p_mult_fine._pointer[0], 257d99fa3c5SJeremy L Thompson rstr_coarse._pointer[0], 258d99fa3c5SJeremy L Thompson basis_coarse._pointer[0], 259d99fa3c5SJeremy L Thompson interpCtoF_pointer, 260d99fa3c5SJeremy L Thompson opCoarsePointer, 261d99fa3c5SJeremy L Thompson opProlongPointer, 262d99fa3c5SJeremy L Thompson opRestrictPointer) 263d99fa3c5SJeremy L Thompson 264d99fa3c5SJeremy L Thompson # Wrap operators 265d99fa3c5SJeremy L Thompson opCoarse = _OperatorWrap( 266d99fa3c5SJeremy L Thompson self._ceed, opCoarsePointer) 267d99fa3c5SJeremy L Thompson opProlong = _OperatorWrap( 268d99fa3c5SJeremy L Thompson self._ceed, opProlongPointer) 269d99fa3c5SJeremy L Thompson opRestrict = _OperatorWrap( 270d99fa3c5SJeremy L Thompson self._ceed, opRestrictPointer) 271d99fa3c5SJeremy L Thompson 272d99fa3c5SJeremy L Thompson # Return 273d99fa3c5SJeremy L Thompson return [opCoarse, opProlong, opRestrict] 274d99fa3c5SJeremy L Thompson 275d99fa3c5SJeremy L Thompson 276f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 2777a7b0fa3SJed Brown 2787a7b0fa3SJed Brown 279f2d2bf5dSjeremyltclass Operator(_OperatorBase): 280f2d2bf5dSjeremylt """Ceed Operator: composed FE-type operations on vectors.""" 281f2d2bf5dSjeremylt 282f2d2bf5dSjeremylt # Constructor 283f2d2bf5dSjeremylt def __init__(self, ceed, qf, dqf=None, dqfT=None): 284f2d2bf5dSjeremylt # CeedOperator object 285f2d2bf5dSjeremylt self._pointer = ffi.new("CeedOperator *") 286f2d2bf5dSjeremylt 287f2d2bf5dSjeremylt # Reference to Ceed 288f2d2bf5dSjeremylt self._ceed = ceed 289f2d2bf5dSjeremylt 290f2d2bf5dSjeremylt # libCEED call 291477729cfSJeremy L Thompson err_code = lib.CeedOperatorCreate(self._ceed._pointer[0], qf._pointer[0], 292f2d2bf5dSjeremylt dqf._pointer[0] if dqf else ffi.NULL, 293f2d2bf5dSjeremylt dqfT._pointer[0] if dqfT else ffi.NULL, 294f2d2bf5dSjeremylt self._pointer) 295477729cfSJeremy L Thompson self._ceed._check_error(err_code) 296f2d2bf5dSjeremylt 297f2d2bf5dSjeremylt # Add field to CeedOperator 298a8d32208Sjeremylt def set_field(self, fieldname, restriction, basis, vector): 299f2d2bf5dSjeremylt """Provide a field to an Operator for use by its QFunction. 300f2d2bf5dSjeremylt 301f2d2bf5dSjeremylt Args: 302f2d2bf5dSjeremylt fieldname: name of the field (to be matched with the same name used 303f2d2bf5dSjeremylt by QFunction) 304f2d2bf5dSjeremylt restriction: ElemRestriction 305f2d2bf5dSjeremylt basis: Basis in which the field resides or CEED_BASIS_COLLOCATED 306f2d2bf5dSjeremylt if collocated with quadrature points 307f2d2bf5dSjeremylt vector: Vector to be used by Operator or CEED_VECTOR_ACTIVE 308f2d2bf5dSjeremylt if field is active or CEED_VECTOR_NONE if using 309a8d32208Sjeremylt CEED_EVAL_WEIGHT in the QFunction""" 310f2d2bf5dSjeremylt 311f2d2bf5dSjeremylt # libCEED call 312f2d2bf5dSjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 313477729cfSJeremy L Thompson err_code = lib.CeedOperatorSetField(self._pointer[0], fieldnameAscii, 314a8d32208Sjeremylt restriction._pointer[0], basis._pointer[0], 315f2d2bf5dSjeremylt vector._pointer[0]) 316477729cfSJeremy L Thompson self._ceed._check_error(err_code) 317f2d2bf5dSjeremylt 318f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 3197a7b0fa3SJed Brown 3207a7b0fa3SJed Brown 321f2d2bf5dSjeremyltclass CompositeOperator(_OperatorBase): 322f2d2bf5dSjeremylt """Ceed Composite Operator: composition of multiple Operators.""" 323f2d2bf5dSjeremylt 324f2d2bf5dSjeremylt # Constructor 325f2d2bf5dSjeremylt def __init__(self, ceed): 326f2d2bf5dSjeremylt # CeedOperator object 327f2d2bf5dSjeremylt self._pointer = ffi.new("CeedOperator *") 328f2d2bf5dSjeremylt 329f2d2bf5dSjeremylt # Reference to Ceed 330f2d2bf5dSjeremylt self._ceed = ceed 331f2d2bf5dSjeremylt # libCEED call 332477729cfSJeremy L Thompson err_code = lib.CeedCompositeOperatorCreate( 333477729cfSJeremy L Thompson self._ceed._pointer[0], self._pointer) 334477729cfSJeremy L Thompson self._ceed._check_error(err_code) 335f2d2bf5dSjeremylt 336f2d2bf5dSjeremylt # Add sub operators 337f2d2bf5dSjeremylt def add_sub(self, subop): 338f2d2bf5dSjeremylt """Add a sub-operator to a composite CeedOperator. 339f2d2bf5dSjeremylt 340f2d2bf5dSjeremylt Args: 341f2d2bf5dSjeremylt subop: sub-operator Operator""" 342f2d2bf5dSjeremylt 343f2d2bf5dSjeremylt # libCEED call 344477729cfSJeremy L Thompson err_code = lib.CeedCompositeOperatorAddSub( 345477729cfSJeremy L Thompson self._pointer[0], subop._pointer[0]) 346477729cfSJeremy L Thompson self._ceed._check_error(err_code) 347f2d2bf5dSjeremylt 348f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 349d99fa3c5SJeremy L Thompson 350d99fa3c5SJeremy L Thompson 351d99fa3c5SJeremy L Thompsonclass _OperatorWrap(Operator): 352d99fa3c5SJeremy L Thompson """Wrap a CeedOperator pointer in a Operator object.""" 353d99fa3c5SJeremy L Thompson 354d99fa3c5SJeremy L Thompson # Constructor 355d99fa3c5SJeremy L Thompson def __init__(self, ceed, pointer): 356d99fa3c5SJeremy L Thompson # CeedOperator object 357d99fa3c5SJeremy L Thompson self._pointer = pointer 358d99fa3c5SJeremy L Thompson 359d99fa3c5SJeremy L Thompson # Reference to Ceed 360d99fa3c5SJeremy L Thompson self._ceed = ceed 361d99fa3c5SJeremy L Thompson 362d99fa3c5SJeremy L Thompson# ------------------------------------------------------------------------------ 363