1*9ba83ac0SJeremy L Thompson# Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors 23d8e8822SJeremy L Thompson# All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3f2d2bf5dSjeremylt# 43d8e8822SJeremy L Thompson# SPDX-License-Identifier: BSD-2-Clause 5f2d2bf5dSjeremylt# 63d8e8822SJeremy L Thompson# This file is part of CEED: http://github.com/ceed 7f2d2bf5dSjeremylt 8f2d2bf5dSjeremyltfrom _ceed_cffi import ffi, lib 9f2d2bf5dSjeremyltimport tempfile 10f2d2bf5dSjeremyltfrom abc import ABC 11f2d2bf5dSjeremyltfrom .ceed_constants import REQUEST_IMMEDIATE, REQUEST_ORDERED, NOTRANSPOSE 12f2d2bf5dSjeremylt 13f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 147a7b0fa3SJed Brown 157a7b0fa3SJed Brown 16f2d2bf5dSjeremyltclass _OperatorBase(ABC): 17f2d2bf5dSjeremylt """Ceed Operator: composed FE-type operations on vectors.""" 18f2d2bf5dSjeremylt 19f2d2bf5dSjeremylt # Destructor 20f2d2bf5dSjeremylt def __del__(self): 21f2d2bf5dSjeremylt # libCEED call 22477729cfSJeremy L Thompson err_code = lib.CeedOperatorDestroy(self._pointer) 23477729cfSJeremy L Thompson self._ceed._check_error(err_code) 24f2d2bf5dSjeremylt 25f2d2bf5dSjeremylt # Representation 26f2d2bf5dSjeremylt def __repr__(self): 27f2d2bf5dSjeremylt return "<CeedOperator instance at " + hex(id(self)) + ">" 28f2d2bf5dSjeremylt 29f2d2bf5dSjeremylt # String conversion for print() to stdout 30f2d2bf5dSjeremylt def __str__(self): 31f2d2bf5dSjeremylt """View an Operator via print().""" 32f2d2bf5dSjeremylt 33f2d2bf5dSjeremylt # libCEED call 34f2d2bf5dSjeremylt with tempfile.NamedTemporaryFile() as key_file: 35f2d2bf5dSjeremylt with open(key_file.name, 'r+') as stream_file: 36f2d2bf5dSjeremylt stream = ffi.cast("FILE *", stream_file) 37f2d2bf5dSjeremylt 38477729cfSJeremy L Thompson err_code = lib.CeedOperatorView(self._pointer[0], stream) 39477729cfSJeremy L Thompson self._ceed._check_error(err_code) 40f2d2bf5dSjeremylt 41f2d2bf5dSjeremylt stream_file.seek(0) 42f2d2bf5dSjeremylt out_string = stream_file.read() 43f2d2bf5dSjeremylt 44f2d2bf5dSjeremylt return out_string 45f2d2bf5dSjeremylt 4628d09c20SJeremy L Thompson # Check Operator setup 4728d09c20SJeremy L Thompson def check(self): 4828d09c20SJeremy L Thompson """Check if a CeedOperator is ready to be used""" 4928d09c20SJeremy L Thompson # libCEED call 5028d09c20SJeremy L Thompson err_code = lib.CeedOperatorCheckReady(self._pointer[0]) 5128d09c20SJeremy L Thompson self._ceed._check_error(err_code) 5228d09c20SJeremy L Thompson 536397b31bSJeremy L Thompson # Assemble linear diagonal 546397b31bSJeremy L Thompson def linear_assemble_diagonal(self, d, request=REQUEST_IMMEDIATE): 556397b31bSJeremy L Thompson """Assemble the diagonal of a square linear Operator 566397b31bSJeremy L Thompson 576397b31bSJeremy L Thompson Args: 586397b31bSJeremy L Thompson d: Vector to store assembled Operator diagonal 596397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 606397b31bSJeremy L Thompson 616397b31bSJeremy L Thompson # libCEED call 62477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleDiagonal(self._pointer[0], 636397b31bSJeremy L Thompson d._pointer[0], request) 64477729cfSJeremy L Thompson self._ceed._check_error(err_code) 656397b31bSJeremy L Thompson 666397b31bSJeremy L Thompson # Assemble add linear diagonal 676397b31bSJeremy L Thompson def linear_assemble_add_diagonal(self, d, request=REQUEST_IMMEDIATE): 686397b31bSJeremy L Thompson """Sum the diagonal of a square linear Operator into a Vector 696397b31bSJeremy L Thompson 706397b31bSJeremy L Thompson Args: 716397b31bSJeremy L Thompson d: Vector to store assembled Operator diagonal 726397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 736397b31bSJeremy L Thompson 746397b31bSJeremy L Thompson # libCEED call 75477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleAddDiagonal(self._pointer[0], 766397b31bSJeremy L Thompson d._pointer[0], request) 77477729cfSJeremy L Thompson self._ceed._check_error(err_code) 786397b31bSJeremy L Thompson 796397b31bSJeremy L Thompson # Assemble linear point block diagonal 800c9255dfSJeremy L Thompson def linear_assemble_point_block_diagonal( 810c9255dfSJeremy L Thompson self, d, request=REQUEST_IMMEDIATE): 820c9255dfSJeremy L Thompson """Assemble the point block diagonal of a square linear Operator 836397b31bSJeremy L Thompson 846397b31bSJeremy L Thompson Args: 856397b31bSJeremy L Thompson d: Vector to store assembled Operator point block diagonal, 866397b31bSJeremy L Thompson provided in row-major form with an ncomp*ncomp block 876397b31bSJeremy L Thompson at each node 886397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 896397b31bSJeremy L Thompson 906397b31bSJeremy L Thompson # libCEED call 91477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssemblePointBlockDiagonal(self._pointer[0], 926397b31bSJeremy L Thompson d._pointer[0], request) 93477729cfSJeremy L Thompson self._ceed._check_error(err_code) 946397b31bSJeremy L Thompson 956397b31bSJeremy L Thompson # Assemble linear point block diagonal 960c9255dfSJeremy L Thompson def linear_assemble_add_point_block_diagonal( 970c9255dfSJeremy L Thompson self, d, request=REQUEST_IMMEDIATE): 980c9255dfSJeremy L Thompson """Sum the point block diagonal of a square linear Operator into a Vector 996397b31bSJeremy L Thompson 1006397b31bSJeremy L Thompson Args: 1016397b31bSJeremy L Thompson d: Vector to store assembled Operator point block diagonal, 1026397b31bSJeremy L Thompson provided in row-major form with an ncomp*ncomp block 1036397b31bSJeremy L Thompson at each node 1046397b31bSJeremy L Thompson **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 1056397b31bSJeremy L Thompson 1066397b31bSJeremy L Thompson # libCEED call 107477729cfSJeremy L Thompson err_code = lib.CeedOperatorLinearAssembleAddPointBlockDiagonal(self._pointer[0], 1086397b31bSJeremy L Thompson d._pointer[0], request) 109477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1106397b31bSJeremy L Thompson 111ea6b5821SJeremy L Thompson # Set name 112ea6b5821SJeremy L Thompson def name(self, name): 113ea6b5821SJeremy L Thompson """Set name of Operator for print output 114ea6b5821SJeremy L Thompson 115ea6b5821SJeremy L Thompson Args: 116ea6b5821SJeremy L Thompson name: Name to set""" 117ea6b5821SJeremy L Thompson 118ea6b5821SJeremy L Thompson name = ffi.new("char[]", name.encode('ascii')) 119ea6b5821SJeremy L Thompson err_code = lib.CeedOperatorSetName(self._pointer[0], name) 120ea6b5821SJeremy L Thompson self._ceed._check_error(err_code) 121ea6b5821SJeremy L Thompson 122f2d2bf5dSjeremylt # Apply CeedOperator 123f2d2bf5dSjeremylt def apply(self, u, v, request=REQUEST_IMMEDIATE): 124f2d2bf5dSjeremylt """Apply Operator to a vector. 125f2d2bf5dSjeremylt 126f2d2bf5dSjeremylt Args: 127f2d2bf5dSjeremylt u: Vector containing input state or CEED_VECTOR_NONE if there are no 128f2d2bf5dSjeremylt active inputs 129f2d2bf5dSjeremylt v: Vector to store result of applying operator (must be distinct from u) 130f2d2bf5dSjeremylt or CEED_VECTOR_NONE if there are no active outputs 131f2d2bf5dSjeremylt **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 132f2d2bf5dSjeremylt 133f2d2bf5dSjeremylt # libCEED call 134477729cfSJeremy L Thompson err_code = lib.CeedOperatorApply(self._pointer[0], u._pointer[0], v._pointer[0], 135f2d2bf5dSjeremylt request) 136477729cfSJeremy L Thompson self._ceed._check_error(err_code) 137f2d2bf5dSjeremylt 138f2d2bf5dSjeremylt # Apply CeedOperator 139f2d2bf5dSjeremylt def apply_add(self, u, v, request=REQUEST_IMMEDIATE): 140f2d2bf5dSjeremylt """Apply Operator to a vector and add result to output vector. 141f2d2bf5dSjeremylt 142f2d2bf5dSjeremylt Args: 143f2d2bf5dSjeremylt u: Vector containing input state or CEED_VECTOR_NONE if there are no 144f2d2bf5dSjeremylt active inputs 145f2d2bf5dSjeremylt v: Vector to sum in result of applying operator (must be distinct from u) 146f2d2bf5dSjeremylt or CEED_VECTOR_NONE if there are no active outputs 147f2d2bf5dSjeremylt **request: Ceed request, default CEED_REQUEST_IMMEDIATE""" 148f2d2bf5dSjeremylt 149f2d2bf5dSjeremylt # libCEED call 150477729cfSJeremy L Thompson err_code = lib.CeedOperatorApplyAdd(self._pointer[0], u._pointer[0], v._pointer[0], 151f2d2bf5dSjeremylt request) 152477729cfSJeremy L Thompson self._ceed._check_error(err_code) 153f2d2bf5dSjeremylt 154d99fa3c5SJeremy L Thompson # Create Multigrid Level 155d99fa3c5SJeremy L Thompson def multigrid_create(self, p_mult_fine, rstr_coarse, basis_coarse): 156d99fa3c5SJeremy L Thompson """ Create a multigrid coarse operator and level transfer operators 157d99fa3c5SJeremy L Thompson for a CeedOperator with a Lagrange tensor basis for the active basis 158d99fa3c5SJeremy L Thompson 159d99fa3c5SJeremy L Thompson Args: 160d99fa3c5SJeremy L Thompson p_mult_fine: L-vector multiplicity in parallel gather/scatter 161d99fa3c5SJeremy L Thompson basis_coarse: Coarse grid active vector basis 162d99fa3c5SJeremy L Thompson degree_coarse: Coarse grid basis polynomial order""" 163d99fa3c5SJeremy L Thompson 164d99fa3c5SJeremy L Thompson # Operator pointers 165d99fa3c5SJeremy L Thompson opCoarsePointer = ffi.new("CeedOperator *") 166d99fa3c5SJeremy L Thompson opProlongPointer = ffi.new("CeedOperator *") 167d99fa3c5SJeremy L Thompson opRestrictPointer = ffi.new("CeedOperator *") 168d99fa3c5SJeremy L Thompson 169d99fa3c5SJeremy L Thompson # libCEED call 170d99fa3c5SJeremy L Thompson lib.CeedOperatorMultigridLevelCreate(self._pointer[0], 171d99fa3c5SJeremy L Thompson p_mult_fine._pointer[0], 172d99fa3c5SJeremy L Thompson rstr_coarse._pointer[0], 173d99fa3c5SJeremy L Thompson basis_coarse._pointer[0], 174d99fa3c5SJeremy L Thompson opCoarsePointer, 175d99fa3c5SJeremy L Thompson opProlongPointer, 176d99fa3c5SJeremy L Thompson opRestrictPointer) 177d99fa3c5SJeremy L Thompson 178d99fa3c5SJeremy L Thompson # Wrap operators 179d99fa3c5SJeremy L Thompson opCoarse = _OperatorWrap( 180d99fa3c5SJeremy L Thompson self._ceed, opCoarsePointer) 181d99fa3c5SJeremy L Thompson opProlong = _OperatorWrap( 182d99fa3c5SJeremy L Thompson self._ceed, opProlongPointer) 183d99fa3c5SJeremy L Thompson opRestrict = _OperatorWrap( 184d99fa3c5SJeremy L Thompson self._ceed, opRestrictPointer) 185d99fa3c5SJeremy L Thompson 186d99fa3c5SJeremy L Thompson # Return 187d99fa3c5SJeremy L Thompson return [opCoarse, opProlong, opRestrict] 188d99fa3c5SJeremy L Thompson 189d99fa3c5SJeremy L Thompson # Create Multigrid Level 190d99fa3c5SJeremy L Thompson def multigrid_create_tensor_h1(self, p_mult_fine, rstr_coarse, basis_coarse, 191d99fa3c5SJeremy L Thompson interp_C_to_F): 192d99fa3c5SJeremy L Thompson """ Create a multigrid coarse operator and level transfer operators 193d99fa3c5SJeremy L Thompson for a CeedOperator with a non-tensor basis for the active basis 194d99fa3c5SJeremy L Thompson 195d99fa3c5SJeremy L Thompson Args: 196d99fa3c5SJeremy L Thompson p_mult_fine: L-vector multiplicity in parallel gather/scatter 197d99fa3c5SJeremy L Thompson rstr_coarse: Coarse grid restriction 198d99fa3c5SJeremy L Thompson basis_coarse: Coarse grid active vector basis 199d99fa3c5SJeremy L Thompson interp_C_to_F: Matrix for coarse to fine interpolation""" 200d99fa3c5SJeremy L Thompson 201d99fa3c5SJeremy L Thompson # Setup arguments 202d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.new("CeedScalar *") 203d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.cast( 204d99fa3c5SJeremy L Thompson "CeedScalar *", 205d99fa3c5SJeremy L Thompson interp_C_to_F.__array_interface__['data'][0]) 206d99fa3c5SJeremy L Thompson 207d99fa3c5SJeremy L Thompson # Operator pointers 208d99fa3c5SJeremy L Thompson opCoarsePointer = ffi.new("CeedOperator *") 209d99fa3c5SJeremy L Thompson opProlongPointer = ffi.new("CeedOperator *") 210d99fa3c5SJeremy L Thompson opRestrictPointer = ffi.new("CeedOperator *") 211d99fa3c5SJeremy L Thompson 212d99fa3c5SJeremy L Thompson # libCEED call 213d99fa3c5SJeremy L Thompson lib.CeedOperatorMultigridLevelCreateTensorH1(self._pointer[0], 214d99fa3c5SJeremy L Thompson p_mult_fine._pointer[0], 215d99fa3c5SJeremy L Thompson rstr_coarse._pointer[0], 216d99fa3c5SJeremy L Thompson basis_coarse._pointer[0], 217d99fa3c5SJeremy L Thompson interpCtoF_pointer, 218d99fa3c5SJeremy L Thompson opCoarsePointer, 219d99fa3c5SJeremy L Thompson opProlongPointer, 220d99fa3c5SJeremy L Thompson opRestrictPointer) 221d99fa3c5SJeremy L Thompson 222d99fa3c5SJeremy L Thompson # Wrap operators 223d99fa3c5SJeremy L Thompson opCoarse = _OperatorWrap( 224d99fa3c5SJeremy L Thompson self._ceed, opCoarsePointer) 225d99fa3c5SJeremy L Thompson opProlong = _OperatorWrap( 226d99fa3c5SJeremy L Thompson self._ceed, opProlongPointer) 227d99fa3c5SJeremy L Thompson opRestrict = _OperatorWrap( 228d99fa3c5SJeremy L Thompson self._ceed, opRestrictPointer) 229d99fa3c5SJeremy L Thompson 230d99fa3c5SJeremy L Thompson # Return 231d99fa3c5SJeremy L Thompson return [opCoarse, opProlong, opRestrict] 232d99fa3c5SJeremy L Thompson 233d99fa3c5SJeremy L Thompson # Create Multigrid Level 234d99fa3c5SJeremy L Thompson def multigrid_create_h1(self, p_mult_fine, rstr_coarse, basis_coarse, 235d99fa3c5SJeremy L Thompson interp_C_to_F): 236d99fa3c5SJeremy L Thompson """ Create a multigrid coarse operator and level transfer operators 237d99fa3c5SJeremy L Thompson for a CeedOperator with a Lagrange tensor basis for the active basis 238d99fa3c5SJeremy L Thompson 239d99fa3c5SJeremy L Thompson Args: 240d99fa3c5SJeremy L Thompson p_mult_fine: L-vector multiplicity in parallel gather/scatter 241d99fa3c5SJeremy L Thompson rstr_coarse: Coarse grid restriction 242d99fa3c5SJeremy L Thompson basis_coarse: Coarse grid active vector basis 243d99fa3c5SJeremy L Thompson interp_C_to_F: Matrix for coarse to fine interpolation""" 244d99fa3c5SJeremy L Thompson 245d99fa3c5SJeremy L Thompson # Setup arguments 246d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.new("CeedScalar *") 247d99fa3c5SJeremy L Thompson interpCtoF_pointer = ffi.cast( 248d99fa3c5SJeremy L Thompson "CeedScalar *", 249d99fa3c5SJeremy L Thompson interp_C_to_F.__array_interface__['data'][0]) 250d99fa3c5SJeremy L Thompson 251d99fa3c5SJeremy L Thompson # Operator pointers 252d99fa3c5SJeremy L Thompson opCoarsePointer = ffi.new("CeedOperator *") 253d99fa3c5SJeremy L Thompson opProlongPointer = ffi.new("CeedOperator *") 254d99fa3c5SJeremy L Thompson opRestrictPointer = ffi.new("CeedOperator *") 255d99fa3c5SJeremy L Thompson 256d99fa3c5SJeremy L Thompson # libCEED call 257d99fa3c5SJeremy L Thompson lib.CeedOperatorMultigridLevelCreateH1(self._pointer[0], 258d99fa3c5SJeremy L Thompson p_mult_fine._pointer[0], 259d99fa3c5SJeremy L Thompson rstr_coarse._pointer[0], 260d99fa3c5SJeremy L Thompson basis_coarse._pointer[0], 261d99fa3c5SJeremy L Thompson interpCtoF_pointer, 262d99fa3c5SJeremy L Thompson opCoarsePointer, 263d99fa3c5SJeremy L Thompson opProlongPointer, 264d99fa3c5SJeremy L Thompson opRestrictPointer) 265d99fa3c5SJeremy L Thompson 266d99fa3c5SJeremy L Thompson # Wrap operators 267d99fa3c5SJeremy L Thompson opCoarse = _OperatorWrap( 268d99fa3c5SJeremy L Thompson self._ceed, opCoarsePointer) 269d99fa3c5SJeremy L Thompson opProlong = _OperatorWrap( 270d99fa3c5SJeremy L Thompson self._ceed, opProlongPointer) 271d99fa3c5SJeremy L Thompson opRestrict = _OperatorWrap( 272d99fa3c5SJeremy L Thompson self._ceed, opRestrictPointer) 273d99fa3c5SJeremy L Thompson 274d99fa3c5SJeremy L Thompson # Return 275d99fa3c5SJeremy L Thompson return [opCoarse, opProlong, opRestrict] 276d99fa3c5SJeremy L Thompson 277d99fa3c5SJeremy L Thompson 278f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 2797a7b0fa3SJed Brown 2807a7b0fa3SJed Brown 281f2d2bf5dSjeremyltclass Operator(_OperatorBase): 282f2d2bf5dSjeremylt """Ceed Operator: composed FE-type operations on vectors.""" 283f2d2bf5dSjeremylt 284f2d2bf5dSjeremylt # Constructor 285f2d2bf5dSjeremylt def __init__(self, ceed, qf, dqf=None, dqfT=None): 286f2d2bf5dSjeremylt # CeedOperator object 287f2d2bf5dSjeremylt self._pointer = ffi.new("CeedOperator *") 288f2d2bf5dSjeremylt 289f2d2bf5dSjeremylt # Reference to Ceed 290f2d2bf5dSjeremylt self._ceed = ceed 291f2d2bf5dSjeremylt 292f2d2bf5dSjeremylt # libCEED call 293477729cfSJeremy L Thompson err_code = lib.CeedOperatorCreate(self._ceed._pointer[0], qf._pointer[0], 294f2d2bf5dSjeremylt dqf._pointer[0] if dqf else ffi.NULL, 295f2d2bf5dSjeremylt dqfT._pointer[0] if dqfT else ffi.NULL, 296f2d2bf5dSjeremylt self._pointer) 297477729cfSJeremy L Thompson self._ceed._check_error(err_code) 298f2d2bf5dSjeremylt 299f2d2bf5dSjeremylt # Add field to CeedOperator 300a8d32208Sjeremylt def set_field(self, fieldname, restriction, basis, vector): 301f2d2bf5dSjeremylt """Provide a field to an Operator for use by its QFunction. 302f2d2bf5dSjeremylt 303f2d2bf5dSjeremylt Args: 304f2d2bf5dSjeremylt fieldname: name of the field (to be matched with the same name used 305f2d2bf5dSjeremylt by QFunction) 306f2d2bf5dSjeremylt restriction: ElemRestriction 307356036faSJeremy L Thompson basis: Basis in which the field resides or CEED_BASIS_NONE 308356036faSJeremy L Thompson if using CEED_EVAL_NONE 309f2d2bf5dSjeremylt vector: Vector to be used by Operator or CEED_VECTOR_ACTIVE 310f2d2bf5dSjeremylt if field is active or CEED_VECTOR_NONE if using 311a8d32208Sjeremylt CEED_EVAL_WEIGHT in the QFunction""" 312f2d2bf5dSjeremylt 313f2d2bf5dSjeremylt # libCEED call 314f2d2bf5dSjeremylt fieldnameAscii = ffi.new("char[]", fieldname.encode('ascii')) 315477729cfSJeremy L Thompson err_code = lib.CeedOperatorSetField(self._pointer[0], fieldnameAscii, 316a8d32208Sjeremylt restriction._pointer[0], basis._pointer[0], 317f2d2bf5dSjeremylt vector._pointer[0]) 318477729cfSJeremy L Thompson self._ceed._check_error(err_code) 319f2d2bf5dSjeremylt 320f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 3217a7b0fa3SJed Brown 3227a7b0fa3SJed Brown 323f2d2bf5dSjeremyltclass CompositeOperator(_OperatorBase): 324f2d2bf5dSjeremylt """Ceed Composite Operator: composition of multiple Operators.""" 325f2d2bf5dSjeremylt 326f2d2bf5dSjeremylt # Constructor 327f2d2bf5dSjeremylt def __init__(self, ceed): 328f2d2bf5dSjeremylt # CeedOperator object 329f2d2bf5dSjeremylt self._pointer = ffi.new("CeedOperator *") 330f2d2bf5dSjeremylt 331f2d2bf5dSjeremylt # Reference to Ceed 332f2d2bf5dSjeremylt self._ceed = ceed 333f2d2bf5dSjeremylt # libCEED call 334ed094490SJeremy L Thompson err_code = lib.CeedOperatorCreateComposite( 335477729cfSJeremy L Thompson self._ceed._pointer[0], self._pointer) 336477729cfSJeremy L Thompson self._ceed._check_error(err_code) 337f2d2bf5dSjeremylt 338f2d2bf5dSjeremylt # Add sub operators 339f2d2bf5dSjeremylt def add_sub(self, subop): 340f2d2bf5dSjeremylt """Add a sub-operator to a composite CeedOperator. 341f2d2bf5dSjeremylt 342f2d2bf5dSjeremylt Args: 343f2d2bf5dSjeremylt subop: sub-operator Operator""" 344f2d2bf5dSjeremylt 345f2d2bf5dSjeremylt # libCEED call 346ed094490SJeremy L Thompson err_code = lib.CeedOperatorCompositeAddSub( 347477729cfSJeremy L Thompson self._pointer[0], subop._pointer[0]) 348477729cfSJeremy L Thompson self._ceed._check_error(err_code) 349f2d2bf5dSjeremylt 350f2d2bf5dSjeremylt# ------------------------------------------------------------------------------ 351d99fa3c5SJeremy L Thompson 352d99fa3c5SJeremy L Thompson 353d99fa3c5SJeremy L Thompsonclass _OperatorWrap(Operator): 354d99fa3c5SJeremy L Thompson """Wrap a CeedOperator pointer in a Operator object.""" 355d99fa3c5SJeremy L Thompson 356d99fa3c5SJeremy L Thompson # Constructor 357d99fa3c5SJeremy L Thompson def __init__(self, ceed, pointer): 358d99fa3c5SJeremy L Thompson # CeedOperator object 359d99fa3c5SJeremy L Thompson self._pointer = pointer 360d99fa3c5SJeremy L Thompson 361d99fa3c5SJeremy L Thompson # Reference to Ceed 362d99fa3c5SJeremy L Thompson self._ceed = ceed 363d99fa3c5SJeremy L Thompson 364d99fa3c5SJeremy L Thompson# ------------------------------------------------------------------------------ 365