xref: /libCEED/julia/LibCEED.jl/src/Operator.jl (revision e64bb3f3ed2986a0c10dec3b47522d734c6e367d)
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