1mutable struct Operator 2 ref::RefValue{C.CeedOperator} 3 qf::AbstractQFunction 4 dqf::AbstractQFunction 5 dqfT::AbstractQFunction 6 sub_ops::Vector{Operator} 7 function Operator(ref, qf, dqf, dqfT) 8 obj = new(ref, qf, dqf, dqfT, []) 9 finalizer(obj) do x 10 # ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.\n", repr(x)) 11 destroy(x) 12 end 13 return obj 14 end 15end 16destroy(op::Operator) = C.CeedOperatorDestroy(op.ref) # COV_EXCL_LINE 17Base.getindex(op::Operator) = op.ref[] 18Base.show(io::IO, ::MIME"text/plain", op::Operator) = ceed_show(io, op, C.CeedOperatorView) 19 20""" 21 Operator(ceed::Ceed; qf, dqf=QFunctionNone(), dqfT=QFunctionNone(), fields) 22 23Creates a libCEED `CeedOperator` object using the given Q-function `qf`, and optionally its 24derivative and derivative transpose. 25 26An array of fields must be provided, where each element of the array is a tuple containing 27the name of the field (as a string or symbol), the corresponding element restriction, basis, 28and vector. 29 30# Examples 31 32Create the operator that builds the Q-data associated with the mass matrix. 33``` 34build_oper = Operator( 35 ceed, 36 qf=build_qfunc, 37 fields=[ 38 (:J, mesh_restr, mesh_basis, CeedVectorActive()), 39 (:w, ElemRestrictionNone(), mesh_basis, CeedVectorNone()), 40 (:qdata, sol_restr_i, BasisNone(), CeedVectorActive()) 41 ] 42) 43``` 44""" 45function Operator(c::Ceed; qf, dqf=QFunctionNone(), dqfT=QFunctionNone(), fields) 46 op = Operator(c, qf, dqf, dqfT) 47 for f ∈ fields 48 set_field!(op, String(f[1]), f[2], f[3], f[4]) 49 end 50 op 51end 52 53function Operator( 54 c::Ceed, 55 qf::AbstractQFunction, 56 dqf::AbstractQFunction, 57 dqfT::AbstractQFunction, 58) 59 ref = Ref{C.CeedOperator}() 60 C.CeedOperatorCreate(c[], qf[], dqf[], dqfT[], ref) 61 Operator(ref, qf, dqf, dqfT) 62end 63 64""" 65 create_composite_operator(c::Ceed, ops) 66 67Create an [`Operator`](@ref) whose action represents the sum of the operators in the 68collection `ops`. 69""" 70function create_composite_operator(c::Ceed, ops) 71 ref = Ref{C.CeedOperator}() 72 C.CeedCompositeOperatorCreate(c[], ref) 73 comp_op = Operator(ref, QFunctionNone(), QFunctionNone(), QFunctionNone()) 74 comp_op.sub_ops = ops 75 for op ∈ ops 76 C.CeedCompositeOperatorAddSub(comp_op[], op[]) 77 end 78 comp_op 79end 80 81function set_field!( 82 op::Operator, 83 fieldname::AbstractString, 84 r::AbstractElemRestriction, 85 b::AbstractBasis, 86 v::AbstractCeedVector, 87) 88 C.CeedOperatorSetField(op[], fieldname, r[], b[], v[]) 89end 90 91""" 92 apply!(op::Operator, vin, vout; request=RequestImmediate()) 93 94Apply the action of the operator `op` to the input vector `vin`, and store the result in the 95output vector `vout`. 96 97For non-blocking application, the user can specify a request object. By default, immediate 98(synchronous) completion is requested. 99""" 100function apply!( 101 op::Operator, 102 vin::AbstractCeedVector, 103 vout::AbstractCeedVector; 104 request=RequestImmediate(), 105) 106 C.CeedOperatorApply(op[], vin[], vout[], request[]) 107end 108 109""" 110 apply_add!(op::Operator, vin, vout; request=RequestImmediate()) 111 112Apply the action of the operator `op` to the input vector `vin`, and add the result to the 113output vector `vout`. 114 115For non-blocking application, the user can specify a request object. By default, immediate 116(synchronous) completion is requested. 117""" 118function apply_add!( 119 op::Operator, 120 vin::AbstractCeedVector, 121 vout::AbstractCeedVector; 122 request=RequestImmediate(), 123) 124 C.CeedOperatorApplyAdd(op[], vin[], vout[], request[]) 125end 126 127""" 128 assemble_diagonal!(op::Operator, diag::CeedVector; request=RequestImmediate()) 129 130Overwrites a [`CeedVector`](@ref) with the diagonal of a linear [`Operator`](@ref). 131 132!!! note "Note:" 133 Currently only [`Operator`](@ref)s with a single field are supported. 134""" 135function assemble_diagonal!(op::Operator, diag::CeedVector; request=RequestImmediate()) 136 C.CeedOperatorLinearAssembleDiagonal(op[], diag[], request[]) 137end 138 139""" 140 assemble_diagonal!(op::Operator, diag::CeedVector; request=RequestImmediate()) 141 142Adds the diagonal of a linear [`Operator`](@ref) to the given [`CeedVector`](@ref). 143 144!!! note "Note:" 145 Currently only [`Operator`](@ref)s with a single field are supported. 146""" 147function assemble_add_diagonal!(op::Operator, diag::CeedVector; request=RequestImmediate()) 148 C.CeedOperatorLinearAssembleAddDiagonal(op[], diag[], request[]) 149end 150