xref: /libCEED/julia/LibCEED.jl/test/runtests.jl (revision b2e3f8ecbfa285d0f4ffde9b24c57cc13f0319fb)
137fad103SWill Paznerusing Test, LibCEED, LinearAlgebra, StaticArrays
237fad103SWill Pazner
304085da3SWill Paznershowstr(x) = sprint(show, MIME("text/plain"), x)
404085da3SWill Paznersummarystr(x) = sprint(summary, x)
580a9ef05SNatalie Beamsgetoutput(fname) =
680a9ef05SNatalie Beams    chomp(read(joinpath(@__DIR__, "output", string(CeedScalar), fname), String))
780a9ef05SNatalie Beams
880a9ef05SNatalie Beamsfunction checkoutput(str, fname)
980a9ef05SNatalie Beams    if str != getoutput(fname)
1080a9ef05SNatalie Beams        write(fname, str)
1180a9ef05SNatalie Beams        return false
1280a9ef05SNatalie Beams    end
1380a9ef05SNatalie Beams    return true
1480a9ef05SNatalie Beamsend
1537fad103SWill Pazner
1637fad103SWill Paznermutable struct CtxData
1737fad103SWill Pazner    io::IOBuffer
1837fad103SWill Pazner    x::Vector{Float64}
1937fad103SWill Paznerend
2037fad103SWill Pazner
2104085da3SWill Paznerconst run_dev_tests = !isrelease() || ("--run-dev-tests" in ARGS)
22f99607bdSWill Pazner
23f99607bdSWill Paznerif run_dev_tests
24a697ff73SWill Pazner    include("rundevtests.jl")
25a697ff73SWill Paznerend
26a697ff73SWill Pazner
27c33c11c1SWill Paznerif !LibCEED.ceedversion_ge(LibCEED.minimum_libceed_version) && !run_dev_tests
28f99607bdSWill Pazner    @warn "Skipping tests because of incompatible libCEED versions."
29f99607bdSWill Paznerelse
30a697ff73SWill Pazner    @testset "LibCEED Release Tests" begin
3104085da3SWill Pazner        @testset "LibCEED" begin
3204085da3SWill Pazner            @test ceedversion() isa VersionNumber
3304085da3SWill Pazner            @test isrelease() isa Bool
3404085da3SWill Pazner            @test isfile(get_libceed_path())
3504085da3SWill Pazner        end
3604085da3SWill Pazner
3737fad103SWill Pazner        @testset "Ceed" begin
3837fad103SWill Pazner            res = "/cpu/self/ref/serial"
3937fad103SWill Pazner            c = Ceed(res)
4037fad103SWill Pazner            @test isdeterministic(c)
4137fad103SWill Pazner            @test getresource(c) == res
4237fad103SWill Pazner            @test !iscuda(c)
4337fad103SWill Pazner            @test get_preferred_memtype(c) == MEM_HOST
4437fad103SWill Pazner            @test_throws LibCEED.CeedError create_interior_qfunction(c, "")
4537fad103SWill Pazner            @test showstr(c) == """
4637fad103SWill Pazner                Ceed
4737fad103SWill Pazner                  Ceed Resource: $res
4837fad103SWill Pazner                  Preferred MemType: host"""
4937fad103SWill Pazner        end
5037fad103SWill Pazner
5137fad103SWill Pazner        @testset "Context" begin
5237fad103SWill Pazner            c = Ceed()
5380a9ef05SNatalie Beams            data = zeros(CeedScalar, 3)
5437fad103SWill Pazner            ctx = Context(c, data)
5537fad103SWill Pazner            @test showstr(ctx) == """
5637fad103SWill Pazner                CeedQFunctionContext
5737fad103SWill Pazner                  Context Data Size: $(sizeof(data))"""
5837fad103SWill Pazner            @test_throws Exception set_data!(ctx, MEM_HOST, OWN_POINTER, data)
5937fad103SWill Pazner        end
6037fad103SWill Pazner
6137fad103SWill Pazner        @testset "CeedVector" begin
6237fad103SWill Pazner            n = 10
6337fad103SWill Pazner            c = Ceed()
6437fad103SWill Pazner            v = CeedVector(c, n)
6537fad103SWill Pazner            @test size(v) == (n,)
6637fad103SWill Pazner            @test length(v) == n
6737fad103SWill Pazner            @test axes(v) == (1:n,)
6837fad103SWill Pazner            @test ndims(v) == 1
6937fad103SWill Pazner            @test ndims(CeedVector) == 1
7037fad103SWill Pazner
7137fad103SWill Pazner            v[] = 0.0
7237fad103SWill Pazner            @test @witharray(a = v, all(a .== 0.0))
7337fad103SWill Pazner
7480a9ef05SNatalie Beams            v1 = rand(CeedScalar, n)
7537fad103SWill Pazner            v2 = CeedVector(c, v1)
7637fad103SWill Pazner            @test @witharray_read(a = v2, mtype = MEM_HOST, a == v1)
7737fad103SWill Pazner            @test Vector(v2) == v1
7837fad103SWill Pazner            v[] = v1
7937fad103SWill Pazner            for p ∈ [1, 2, Inf]
8037fad103SWill Pazner                @test norm(v, p) ≈ norm(v1, p)
8137fad103SWill Pazner            end
8237fad103SWill Pazner            @test_throws Exception norm(v, 3)
8337fad103SWill Pazner            @test witharray_read(sum, v) == sum(v1)
8437fad103SWill Pazner            reciprocal!(v)
8580a9ef05SNatalie Beams            @test @witharray(a = v, mtype = MEM_HOST, all(a .== CeedScalar(1.0)./v1))
8637fad103SWill Pazner
8737fad103SWill Pazner            witharray(x -> x .= 1.0, v)
8837fad103SWill Pazner            @test @witharray(a = v, all(a .== 1.0))
8937fad103SWill Pazner
9037fad103SWill Pazner            @test summarystr(v) == "$n-element CeedVector"
91f99607bdSWill Pazner            @test sprint(show, v) == @witharray_read(a = v, sprint(show, a))
92f99607bdSWill Pazner            io = IOBuffer()
93f99607bdSWill Pazner            summary(io, v)
94f99607bdSWill Pazner            println(io, ":")
95f99607bdSWill Pazner            @witharray_read(a = v, Base.print_array(io, a))
96f99607bdSWill Pazner            s1 = String(take!(io))
97f99607bdSWill Pazner            @test showstr(v) == s1
98f99607bdSWill Pazner
99f99607bdSWill Pazner            setarray!(v, MEM_HOST, USE_POINTER, v1)
100f99607bdSWill Pazner            syncarray!(v, MEM_HOST)
101f99607bdSWill Pazner            @test @witharray_read(a = v, a == v1)
102f99607bdSWill Pazner            p = takearray!(v, MEM_HOST)
103f99607bdSWill Pazner            @test p == pointer(v1)
104f99607bdSWill Pazner
10580a9ef05SNatalie Beams            m = rand(CeedScalar, 10, 10)
106f99607bdSWill Pazner            vm = CeedVector(c, vec(m))
107f99607bdSWill Pazner            @test @witharray_read(a = vm, size = size(m), a == m)
108f99607bdSWill Pazner
109f99607bdSWill Pazner            @test CeedVectorActive()[] == LibCEED.C.CEED_VECTOR_ACTIVE[]
110f99607bdSWill Pazner            @test CeedVectorNone()[] == LibCEED.C.CEED_VECTOR_NONE[]
111f99607bdSWill Pazner
11280a9ef05SNatalie Beams            w1 = rand(CeedScalar, n)
11380a9ef05SNatalie Beams            w2 = rand(CeedScalar, n)
11480a9ef05SNatalie Beams            w3 = rand(CeedScalar, n)
115f99607bdSWill Pazner
116f99607bdSWill Pazner            cv1 = CeedVector(c, w1)
117f99607bdSWill Pazner            cv2 = CeedVector(c, w2)
118f99607bdSWill Pazner            cv3 = CeedVector(c, w3)
119f99607bdSWill Pazner
12080a9ef05SNatalie Beams            alpha = rand(CeedScalar)
121f99607bdSWill Pazner
122f99607bdSWill Pazner            scale!(cv1, alpha)
123f99607bdSWill Pazner            w1 .*= alpha
124f99607bdSWill Pazner            @test @witharray_read(a = cv1, a == w1)
125f99607bdSWill Pazner
126f99607bdSWill Pazner            pointwisemult!(cv1, cv2, cv3)
127f99607bdSWill Pazner            w1 .= w2.*w3
128f99607bdSWill Pazner            @test @witharray_read(a = cv1, a == w1)
129f99607bdSWill Pazner
130f99607bdSWill Pazner            axpy!(alpha, cv2, cv1)
131f99607bdSWill Pazner            axpy!(alpha, w2, w1)
132f99607bdSWill Pazner            @test @witharray_read(a = cv1, a ≈ w1)
133f99607bdSWill Pazner        end
13437fad103SWill Pazner
13537fad103SWill Pazner        @testset "Basis" begin
13637fad103SWill Pazner            c = Ceed()
13737fad103SWill Pazner            dim = 3
13837fad103SWill Pazner            ncomp = 1
13937fad103SWill Pazner            p = 4
14037fad103SWill Pazner            q = 6
14137fad103SWill Pazner            b1 = create_tensor_h1_lagrange_basis(c, dim, ncomp, p, q, GAUSS_LOBATTO)
14237fad103SWill Pazner
14380a9ef05SNatalie Beams            @test checkoutput(showstr(b1), "b1.out")
14437fad103SWill Pazner            @test getdimension(b1) == 3
14537fad103SWill Pazner            @test gettopology(b1) == HEX
14637fad103SWill Pazner            @test getnumcomponents(b1) == ncomp
14737fad103SWill Pazner            @test getnumnodes(b1) == p^dim
14837fad103SWill Pazner            @test getnumnodes1d(b1) == p
14937fad103SWill Pazner            @test getnumqpts(b1) == q^dim
15037fad103SWill Pazner            @test getnumqpts1d(b1) == q
15137fad103SWill Pazner
15237fad103SWill Pazner            q1d, w1d = lobatto_quadrature(3, AbscissaAndWeights)
15380a9ef05SNatalie Beams            @test q1d ≈ CeedScalar[-1.0, 0.0, 1.0]
15480a9ef05SNatalie Beams            @test w1d ≈ CeedScalar[1/3, 4/3, 1/3]
15537fad103SWill Pazner
15637fad103SWill Pazner            q1d, w1d = gauss_quadrature(3)
15780a9ef05SNatalie Beams            @test q1d ≈ CeedScalar[-sqrt(3/5), 0.0, sqrt(3/5)]
15880a9ef05SNatalie Beams            @test w1d ≈ CeedScalar[5/9, 8/9, 5/9]
15937fad103SWill Pazner
16080a9ef05SNatalie Beams            b1d = CeedScalar[1.0 0.0; 0.5 0.5; 0.0 1.0]
16180a9ef05SNatalie Beams            d1d = CeedScalar[-0.5 0.5; -0.5 0.5; -0.5 0.5]
16280a9ef05SNatalie Beams            q1d = CeedScalar[-1.0, 0.0, 1.0]
16380a9ef05SNatalie Beams            w1d = CeedScalar[1/3, 4/3, 1/3]
16437fad103SWill Pazner            q, p = size(b1d)
16580a9ef05SNatalie Beams            d2d = zeros(CeedScalar, 2, q*q, p*p)
16637fad103SWill Pazner            d2d[1, :, :] = kron(b1d, d1d)
16737fad103SWill Pazner            d2d[2, :, :] = kron(d1d, b1d)
16837fad103SWill Pazner
16937fad103SWill Pazner            dim2 = 2
17037fad103SWill Pazner            b2 = create_tensor_h1_basis(c, dim2, 1, p, q, b1d, d1d, q1d, w1d)
17137fad103SWill Pazner            @test getinterp(b2) == kron(b1d, b1d)
17237fad103SWill Pazner            @test getinterp1d(b2) == b1d
17337fad103SWill Pazner            @test getgrad(b2) == d2d
17437fad103SWill Pazner            @test getgrad1d(b2) == d1d
17580a9ef05SNatalie Beams            @test checkoutput(showstr(b2), "b2.out")
17637fad103SWill Pazner
177*b2e3f8ecSSebastian Grimberg            b3 = create_h1_basis(
178*b2e3f8ecSSebastian Grimberg                c,
179*b2e3f8ecSSebastian Grimberg                LINE,
180*b2e3f8ecSSebastian Grimberg                1,
181*b2e3f8ecSSebastian Grimberg                p,
182*b2e3f8ecSSebastian Grimberg                q,
183*b2e3f8ecSSebastian Grimberg                b1d,
184*b2e3f8ecSSebastian Grimberg                reshape(d1d, 1, q, p),
185*b2e3f8ecSSebastian Grimberg                reshape(q1d, 1, q),
186*b2e3f8ecSSebastian Grimberg                w1d,
187*b2e3f8ecSSebastian Grimberg            )
188*b2e3f8ecSSebastian Grimberg            @test getqref(b3) == reshape(q1d, 1, q)
18937fad103SWill Pazner            @test getqweights(b3) == w1d
19080a9ef05SNatalie Beams            @test checkoutput(showstr(b3), "b3.out")
19137fad103SWill Pazner
19280a9ef05SNatalie Beams            v = rand(CeedScalar, 2)
19337fad103SWill Pazner            vq = apply(b3, v)
19437fad103SWill Pazner            vd = apply(b3, v; emode=EVAL_GRAD)
19537fad103SWill Pazner            @test vq ≈ b1d*v
19637fad103SWill Pazner            @test vd ≈ d1d*v
19737fad103SWill Pazner
19837fad103SWill Pazner            @test BasisCollocated()[] == LibCEED.C.CEED_BASIS_COLLOCATED[]
19937fad103SWill Pazner        end
20037fad103SWill Pazner
20137fad103SWill Pazner        @testset "Request" begin
20237fad103SWill Pazner            @test RequestImmediate()[] == LibCEED.C.CEED_REQUEST_IMMEDIATE[]
20337fad103SWill Pazner            @test RequestOrdered()[] == LibCEED.C.CEED_REQUEST_ORDERED[]
20437fad103SWill Pazner        end
20537fad103SWill Pazner
20637fad103SWill Pazner        @testset "Misc" begin
20737fad103SWill Pazner            for dim = 1:3
20837fad103SWill Pazner                D = CeedDim(dim)
20980a9ef05SNatalie Beams                J = rand(CeedScalar, dim, dim)
21037fad103SWill Pazner                @test det(J, D) ≈ det(J)
21137fad103SWill Pazner                J = J + J' # make symmetric
21237fad103SWill Pazner                @test setvoigt(SMatrix{dim,dim}(J)) == setvoigt(J, D)
21337fad103SWill Pazner                @test getvoigt(setvoigt(J, D)) == J
21480a9ef05SNatalie Beams                V = zeros(CeedScalar, dim*(dim + 1)÷2)
21537fad103SWill Pazner                setvoigt!(V, J, D)
21637fad103SWill Pazner                @test V == setvoigt(J, D)
21780a9ef05SNatalie Beams                J2 = zeros(CeedScalar, dim, dim)
21837fad103SWill Pazner                getvoigt!(J2, V, D)
21937fad103SWill Pazner                @test J2 == J
22037fad103SWill Pazner            end
22137fad103SWill Pazner        end
22237fad103SWill Pazner
22337fad103SWill Pazner        @testset "Operator" begin
22437fad103SWill Pazner            c = Ceed()
22537fad103SWill Pazner            @interior_qf id = (
22637fad103SWill Pazner                c,
22737fad103SWill Pazner                (input, :in, EVAL_INTERP),
22837fad103SWill Pazner                (output, :out, EVAL_INTERP),
22937fad103SWill Pazner                begin
23037fad103SWill Pazner                    output[] = input
23137fad103SWill Pazner                end,
23237fad103SWill Pazner            )
23337fad103SWill Pazner            b = create_tensor_h1_lagrange_basis(c, 3, 1, 3, 3, GAUSS_LOBATTO)
23437fad103SWill Pazner            n = getnumnodes(b)
23537fad103SWill Pazner            offsets = Vector{CeedInt}(0:n-1)
23637fad103SWill Pazner            r = create_elem_restriction(c, 1, n, 1, 1, n, offsets)
23737fad103SWill Pazner            op = Operator(
23837fad103SWill Pazner                c;
23937fad103SWill Pazner                qf=id,
24037fad103SWill Pazner                fields=[
24137fad103SWill Pazner                    (:input, r, b, CeedVectorActive()),
24237fad103SWill Pazner                    (:output, r, b, CeedVectorActive()),
24337fad103SWill Pazner                ],
24437fad103SWill Pazner            )
24537fad103SWill Pazner
24680a9ef05SNatalie Beams            v = rand(CeedScalar, n)
24737fad103SWill Pazner            v1 = CeedVector(c, v)
24837fad103SWill Pazner            v2 = CeedVector(c, n)
24937fad103SWill Pazner            apply!(op, v1, v2)
25037fad103SWill Pazner            @test @witharray_read(a1 = v1, @witharray_read(a2 = v2, a1 == a2))
25137fad103SWill Pazner            apply_add!(op, v1, v2)
25237fad103SWill Pazner            @test @witharray_read(a1 = v1, @witharray_read(a2 = v2, a1 + a1 == a2))
25337fad103SWill Pazner
25437fad103SWill Pazner            diag_vector = create_lvector(r)
25537fad103SWill Pazner            LibCEED.assemble_diagonal!(op, diag_vector)
25637fad103SWill Pazner            @test @witharray_read(a = diag_vector, a == ones(n))
25737fad103SWill Pazner            # TODO: change this test after bug-fix in libCEED
25837fad103SWill Pazner            diag_vector[] = 0.0
25937fad103SWill Pazner            LibCEED.assemble_add_diagonal!(op, diag_vector)
26037fad103SWill Pazner            @test @witharray(a = diag_vector, a == fill(1.0, n))
26137fad103SWill Pazner
26237fad103SWill Pazner            comp_op = create_composite_operator(c, [op])
26337fad103SWill Pazner            apply!(comp_op, v1, v2)
26437fad103SWill Pazner            @test @witharray_read(a1 = v1, @witharray_read(a2 = v2, a1 == a2))
265bd9c22baSWill Pazner
266bd9c22baSWill Pazner            @test showstr(op) == """
267bd9c22baSWill Pazner                CeedOperator
268bd9c22baSWill Pazner                  1 elements with 27 quadrature points each
269bd9c22baSWill Pazner                  2 fields
270bd9c22baSWill Pazner                  1 input field:
271bd9c22baSWill Pazner                    Input field 0:
272bd9c22baSWill Pazner                      Name: "input"
273bd9c22baSWill Pazner                      Size: 1
274bd9c22baSWill Pazner                      EvalMode: interpolation
275bd9c22baSWill Pazner                      Active vector
276bd9c22baSWill Pazner                  1 output field:
277bd9c22baSWill Pazner                    Output field 0:
278bd9c22baSWill Pazner                      Name: "output"
279bd9c22baSWill Pazner                      Size: 1
280bd9c22baSWill Pazner                      EvalMode: interpolation
281bd9c22baSWill Pazner                      Active vector"""
28237fad103SWill Pazner        end
28337fad103SWill Pazner
28437fad103SWill Pazner        @testset "ElemRestriction" begin
28537fad103SWill Pazner            c = Ceed()
28637fad103SWill Pazner            n = 10
28737fad103SWill Pazner            offsets = Vector{CeedInt}([0:n-1; n-1:2*n-2])
28837fad103SWill Pazner            lsize = 2*n - 1
28937fad103SWill Pazner            r = create_elem_restriction(c, 2, n, 1, lsize, lsize, offsets)
29037fad103SWill Pazner            @test getcompstride(r) == lsize
29137fad103SWill Pazner            @test getnumelements(r) == 2
29237fad103SWill Pazner            @test getelementsize(r) == n
29337fad103SWill Pazner            @test getlvectorsize(r) == lsize
29437fad103SWill Pazner            @test getnumcomponents(r) == 1
29537fad103SWill Pazner            @test length(create_lvector(r)) == lsize
29637fad103SWill Pazner            @test length(create_evector(r)) == 2*n
29737fad103SWill Pazner            lv, ev = create_vectors(r)
29837fad103SWill Pazner            @test length(lv) == lsize
29937fad103SWill Pazner            @test length(ev) == 2*n
30037fad103SWill Pazner            mult = getmultiplicity(r)
30137fad103SWill Pazner            mult2 = ones(lsize)
30237fad103SWill Pazner            mult2[n] = 2
30337fad103SWill Pazner            @test mult == mult2
30480a9ef05SNatalie Beams            rand_lv = rand(CeedScalar, lsize)
30537fad103SWill Pazner            rand_ev = [rand_lv[1:n]; rand_lv[n:end]]
30637fad103SWill Pazner            @test apply(r, rand_lv) == rand_ev
30737fad103SWill Pazner            @test apply(r, rand_ev; tmode=TRANSPOSE) == rand_lv.*mult
30837fad103SWill Pazner            @test showstr(r) == string(
30937fad103SWill Pazner                "CeedElemRestriction from (19, 1) to 2 elements ",
31037fad103SWill Pazner                "with 10 nodes each and component stride 19",
31137fad103SWill Pazner            )
31237fad103SWill Pazner
31337fad103SWill Pazner            strides = CeedInt[1, n, n]
31437fad103SWill Pazner            rs = create_elem_restriction_strided(c, 1, n, 1, n, strides)
31537fad103SWill Pazner            @test showstr(rs) == string(
31637fad103SWill Pazner                "CeedElemRestriction from (10, 1) to 1 elements ",
31737fad103SWill Pazner                "with 10 nodes each and strides [1, $n, $n]",
31837fad103SWill Pazner            )
31937fad103SWill Pazner
32037fad103SWill Pazner            @test ElemRestrictionNone()[] == LibCEED.C.CEED_ELEMRESTRICTION_NONE[]
32137fad103SWill Pazner        end
322bd9c22baSWill Pazner
323bd9c22baSWill Pazner        @testset "QFunction" begin
324bd9c22baSWill Pazner            c = Ceed()
325bd9c22baSWill Pazner            @test showstr(create_interior_qfunction(c, "Poisson3DApply")) == """
326bd9c22baSWill Pazner                 Gallery CeedQFunction - Poisson3DApply
327bd9c22baSWill Pazner                   2 input fields:
328bd9c22baSWill Pazner                     Input field 0:
329bd9c22baSWill Pazner                       Name: "du"
330bd9c22baSWill Pazner                       Size: 3
331bd9c22baSWill Pazner                       EvalMode: "gradient"
332bd9c22baSWill Pazner                     Input field 1:
333bd9c22baSWill Pazner                       Name: "qdata"
334bd9c22baSWill Pazner                       Size: 6
335bd9c22baSWill Pazner                       EvalMode: "none"
336bd9c22baSWill Pazner                   1 output field:
337bd9c22baSWill Pazner                     Output field 0:
338bd9c22baSWill Pazner                       Name: "dv"
339bd9c22baSWill Pazner                       Size: 3
340bd9c22baSWill Pazner                       EvalMode: "gradient\""""
341bd9c22baSWill Pazner
342bd9c22baSWill Pazner            id = create_identity_qfunction(c, 1, EVAL_INTERP, EVAL_INTERP)
343bd9c22baSWill Pazner            Q = 10
344bd9c22baSWill Pazner            v = rand(CeedScalar, Q)
345bd9c22baSWill Pazner            v1 = CeedVector(c, v)
346bd9c22baSWill Pazner            v2 = CeedVector(c, Q)
347bd9c22baSWill Pazner            apply!(id, Q, [v1], [v2])
348bd9c22baSWill Pazner            @test @witharray(a = v2, a == v)
349bd9c22baSWill Pazner
350bd9c22baSWill Pazner            @interior_qf id2 = (c, (a, :in, EVAL_INTERP), (b, :out, EVAL_INTERP), b .= a)
351bd9c22baSWill Pazner            v2[] = 0.0
352bd9c22baSWill Pazner            apply!(id2, Q, [v1], [v2])
353bd9c22baSWill Pazner            @test @witharray(a = v2, a == v)
354bd9c22baSWill Pazner
355bd9c22baSWill Pazner            ctxdata = CtxData(IOBuffer(), rand(CeedScalar, 3))
356bd9c22baSWill Pazner            ctx = Context(c, ctxdata)
357bd9c22baSWill Pazner            dim = 3
358bd9c22baSWill Pazner            @interior_qf qf = (
359bd9c22baSWill Pazner                c,
360bd9c22baSWill Pazner                dim=dim,
361bd9c22baSWill Pazner                ctxdata::CtxData,
362bd9c22baSWill Pazner                (a, :in, EVAL_GRAD, dim),
363bd9c22baSWill Pazner                (b, :in, EVAL_NONE),
364bd9c22baSWill Pazner                (c, :out, EVAL_INTERP),
365bd9c22baSWill Pazner                begin
366bd9c22baSWill Pazner                    c[] = b*sum(a)
367bd9c22baSWill Pazner                    show(ctxdata.io, MIME("text/plain"), ctxdata.x)
368bd9c22baSWill Pazner                end,
369bd9c22baSWill Pazner            )
370bd9c22baSWill Pazner            set_context!(qf, ctx)
371bd9c22baSWill Pazner            in_sz, out_sz = LibCEED.get_field_sizes(qf)
372bd9c22baSWill Pazner            @test in_sz == [dim, 1]
373bd9c22baSWill Pazner            @test out_sz == [1]
374bd9c22baSWill Pazner            v1 = rand(CeedScalar, dim)
375bd9c22baSWill Pazner            v2 = rand(CeedScalar, 1)
376bd9c22baSWill Pazner            cv1 = CeedVector(c, v1)
377bd9c22baSWill Pazner            cv2 = CeedVector(c, v2)
378bd9c22baSWill Pazner            cv3 = CeedVector(c, 1)
379bd9c22baSWill Pazner            apply!(qf, 1, [cv1, cv2], [cv3])
380bd9c22baSWill Pazner            @test String(take!(ctxdata.io)) == showstr(ctxdata.x)
381bd9c22baSWill Pazner            @test @witharray_read(v3 = cv3, v3[1] == v2[1]*sum(v1))
382bd9c22baSWill Pazner
383bd9c22baSWill Pazner            @test QFunctionNone()[] == LibCEED.C.CEED_QFUNCTION_NONE[]
384bd9c22baSWill Pazner        end
38537fad103SWill Pazner    end
386f99607bdSWill Paznerend
387