xref: /libCEED/julia/LibCEED.jl/test/runtests.jl (revision 77bb289ab1e4b7f6618bd6e1f5afbd06578dc0f7)
137fad103SWill Paznerusing Test, LibCEED, LinearAlgebra, StaticArrays
237fad103SWill Pazner
3*77bb289aSJed Browninclude("buildmats.jl")
4*77bb289aSJed Brown
504085da3SWill Paznershowstr(x) = sprint(show, MIME("text/plain"), x)
604085da3SWill Paznersummarystr(x) = sprint(summary, x)
780a9ef05SNatalie Beamsgetoutput(fname) =
880a9ef05SNatalie Beams    chomp(read(joinpath(@__DIR__, "output", string(CeedScalar), fname), String))
980a9ef05SNatalie Beams
1080a9ef05SNatalie Beamsfunction checkoutput(str, fname)
1180a9ef05SNatalie Beams    if str != getoutput(fname)
1280a9ef05SNatalie Beams        write(fname, str)
1380a9ef05SNatalie Beams        return false
1480a9ef05SNatalie Beams    end
1580a9ef05SNatalie Beams    return true
1680a9ef05SNatalie Beamsend
1737fad103SWill Pazner
1837fad103SWill Paznermutable struct CtxData
1937fad103SWill Pazner    io::IOBuffer
2037fad103SWill Pazner    x::Vector{Float64}
2137fad103SWill Paznerend
2237fad103SWill Pazner
2304085da3SWill Paznerconst run_dev_tests = !isrelease() || ("--run-dev-tests" in ARGS)
24f99607bdSWill Pazner
25f99607bdSWill Paznerif run_dev_tests
26a697ff73SWill Pazner    include("rundevtests.jl")
27a697ff73SWill Paznerend
28a697ff73SWill Pazner
29c33c11c1SWill Paznerif !LibCEED.ceedversion_ge(LibCEED.minimum_libceed_version) && !run_dev_tests
30f99607bdSWill Pazner    @warn "Skipping tests because of incompatible libCEED versions."
31f99607bdSWill Paznerelse
32a697ff73SWill Pazner    @testset "LibCEED Release Tests" begin
3304085da3SWill Pazner        @testset "LibCEED" begin
3404085da3SWill Pazner            @test ceedversion() isa VersionNumber
3504085da3SWill Pazner            @test isrelease() isa Bool
3604085da3SWill Pazner            @test isfile(get_libceed_path())
3704085da3SWill Pazner        end
3804085da3SWill Pazner
3937fad103SWill Pazner        @testset "Ceed" begin
4037fad103SWill Pazner            res = "/cpu/self/ref/serial"
4137fad103SWill Pazner            c = Ceed(res)
4237fad103SWill Pazner            @test isdeterministic(c)
4337fad103SWill Pazner            @test getresource(c) == res
4437fad103SWill Pazner            @test !iscuda(c)
4537fad103SWill Pazner            @test get_preferred_memtype(c) == MEM_HOST
4637fad103SWill Pazner            @test_throws LibCEED.CeedError create_interior_qfunction(c, "")
4737fad103SWill Pazner            @test showstr(c) == """
4837fad103SWill Pazner                Ceed
4937fad103SWill Pazner                  Ceed Resource: $res
5037fad103SWill Pazner                  Preferred MemType: host"""
5137fad103SWill Pazner        end
5237fad103SWill Pazner
5337fad103SWill Pazner        @testset "Context" begin
5437fad103SWill Pazner            c = Ceed()
5580a9ef05SNatalie Beams            data = zeros(CeedScalar, 3)
5637fad103SWill Pazner            ctx = Context(c, data)
5737fad103SWill Pazner            @test showstr(ctx) == """
5837fad103SWill Pazner                CeedQFunctionContext
5937fad103SWill Pazner                  Context Data Size: $(sizeof(data))"""
6037fad103SWill Pazner            @test_throws Exception set_data!(ctx, MEM_HOST, OWN_POINTER, data)
6137fad103SWill Pazner        end
6237fad103SWill Pazner
6337fad103SWill Pazner        @testset "CeedVector" begin
6437fad103SWill Pazner            n = 10
6537fad103SWill Pazner            c = Ceed()
6637fad103SWill Pazner            v = CeedVector(c, n)
6737fad103SWill Pazner            @test size(v) == (n,)
6837fad103SWill Pazner            @test length(v) == n
6937fad103SWill Pazner            @test axes(v) == (1:n,)
7037fad103SWill Pazner            @test ndims(v) == 1
7137fad103SWill Pazner            @test ndims(CeedVector) == 1
7237fad103SWill Pazner
7337fad103SWill Pazner            v[] = 0.0
7437fad103SWill Pazner            @test @witharray(a = v, all(a .== 0.0))
7537fad103SWill Pazner
7680a9ef05SNatalie Beams            v1 = rand(CeedScalar, n)
7737fad103SWill Pazner            v2 = CeedVector(c, v1)
7837fad103SWill Pazner            @test @witharray_read(a = v2, mtype = MEM_HOST, a == v1)
7937fad103SWill Pazner            @test Vector(v2) == v1
8037fad103SWill Pazner            v[] = v1
8137fad103SWill Pazner            for p ∈ [1, 2, Inf]
8237fad103SWill Pazner                @test norm(v, p) ≈ norm(v1, p)
8337fad103SWill Pazner            end
8437fad103SWill Pazner            @test_throws Exception norm(v, 3)
8537fad103SWill Pazner            @test witharray_read(sum, v) == sum(v1)
8637fad103SWill Pazner            reciprocal!(v)
8780a9ef05SNatalie Beams            @test @witharray(a = v, mtype = MEM_HOST, all(a .== CeedScalar(1.0)./v1))
8837fad103SWill Pazner
8937fad103SWill Pazner            witharray(x -> x .= 1.0, v)
9037fad103SWill Pazner            @test @witharray(a = v, all(a .== 1.0))
9137fad103SWill Pazner
9237fad103SWill Pazner            @test summarystr(v) == "$n-element CeedVector"
93f99607bdSWill Pazner            @test sprint(show, v) == @witharray_read(a = v, sprint(show, a))
94f99607bdSWill Pazner            io = IOBuffer()
95f99607bdSWill Pazner            summary(io, v)
96f99607bdSWill Pazner            println(io, ":")
97f99607bdSWill Pazner            @witharray_read(a = v, Base.print_array(io, a))
98f99607bdSWill Pazner            s1 = String(take!(io))
99f99607bdSWill Pazner            @test showstr(v) == s1
100f99607bdSWill Pazner
101f99607bdSWill Pazner            setarray!(v, MEM_HOST, USE_POINTER, v1)
102f99607bdSWill Pazner            syncarray!(v, MEM_HOST)
103f99607bdSWill Pazner            @test @witharray_read(a = v, a == v1)
104f99607bdSWill Pazner            p = takearray!(v, MEM_HOST)
105f99607bdSWill Pazner            @test p == pointer(v1)
106f99607bdSWill Pazner
10780a9ef05SNatalie Beams            m = rand(CeedScalar, 10, 10)
108f99607bdSWill Pazner            vm = CeedVector(c, vec(m))
109f99607bdSWill Pazner            @test @witharray_read(a = vm, size = size(m), a == m)
110f99607bdSWill Pazner
111f99607bdSWill Pazner            @test CeedVectorActive()[] == LibCEED.C.CEED_VECTOR_ACTIVE[]
112f99607bdSWill Pazner            @test CeedVectorNone()[] == LibCEED.C.CEED_VECTOR_NONE[]
113f99607bdSWill Pazner
11480a9ef05SNatalie Beams            w1 = rand(CeedScalar, n)
11580a9ef05SNatalie Beams            w2 = rand(CeedScalar, n)
11680a9ef05SNatalie Beams            w3 = rand(CeedScalar, n)
117f99607bdSWill Pazner
118f99607bdSWill Pazner            cv1 = CeedVector(c, w1)
119f99607bdSWill Pazner            cv2 = CeedVector(c, w2)
120f99607bdSWill Pazner            cv3 = CeedVector(c, w3)
121f99607bdSWill Pazner
12280a9ef05SNatalie Beams            alpha = rand(CeedScalar)
123f99607bdSWill Pazner
124f99607bdSWill Pazner            scale!(cv1, alpha)
125f99607bdSWill Pazner            w1 .*= alpha
126f99607bdSWill Pazner            @test @witharray_read(a = cv1, a == w1)
127f99607bdSWill Pazner
128f99607bdSWill Pazner            pointwisemult!(cv1, cv2, cv3)
129f99607bdSWill Pazner            w1 .= w2.*w3
130f99607bdSWill Pazner            @test @witharray_read(a = cv1, a == w1)
131f99607bdSWill Pazner
132f99607bdSWill Pazner            axpy!(alpha, cv2, cv1)
133f99607bdSWill Pazner            axpy!(alpha, w2, w1)
134f99607bdSWill Pazner            @test @witharray_read(a = cv1, a ≈ w1)
135f99607bdSWill Pazner        end
13637fad103SWill Pazner
13737fad103SWill Pazner        @testset "Basis" begin
13837fad103SWill Pazner            c = Ceed()
13937fad103SWill Pazner            dim = 3
14037fad103SWill Pazner            ncomp = 1
14137fad103SWill Pazner            p = 4
14237fad103SWill Pazner            q = 6
14337fad103SWill Pazner            b1 = create_tensor_h1_lagrange_basis(c, dim, ncomp, p, q, GAUSS_LOBATTO)
14437fad103SWill Pazner
14537fad103SWill Pazner            @test getdimension(b1) == 3
14637fad103SWill Pazner            @test gettopology(b1) == HEX
14737fad103SWill Pazner            @test getnumcomponents(b1) == ncomp
14837fad103SWill Pazner            @test getnumnodes(b1) == p^dim
14937fad103SWill Pazner            @test getnumnodes1d(b1) == p
15037fad103SWill Pazner            @test getnumqpts(b1) == q^dim
15137fad103SWill Pazner            @test getnumqpts1d(b1) == q
15237fad103SWill Pazner
15337fad103SWill Pazner            q1d, w1d = lobatto_quadrature(3, AbscissaAndWeights)
15480a9ef05SNatalie Beams            @test q1d ≈ CeedScalar[-1.0, 0.0, 1.0]
15580a9ef05SNatalie Beams            @test w1d ≈ CeedScalar[1/3, 4/3, 1/3]
15637fad103SWill Pazner
15737fad103SWill Pazner            q1d, w1d = gauss_quadrature(3)
15880a9ef05SNatalie Beams            @test q1d ≈ CeedScalar[-sqrt(3/5), 0.0, sqrt(3/5)]
15980a9ef05SNatalie Beams            @test w1d ≈ CeedScalar[5/9, 8/9, 5/9]
16037fad103SWill Pazner
16180a9ef05SNatalie Beams            b1d = CeedScalar[1.0 0.0; 0.5 0.5; 0.0 1.0]
16280a9ef05SNatalie Beams            d1d = CeedScalar[-0.5 0.5; -0.5 0.5; -0.5 0.5]
16380a9ef05SNatalie Beams            q1d = CeedScalar[-1.0, 0.0, 1.0]
16480a9ef05SNatalie Beams            w1d = CeedScalar[1/3, 4/3, 1/3]
16537fad103SWill Pazner            q, p = size(b1d)
16680a9ef05SNatalie Beams            d2d = zeros(CeedScalar, 2, q*q, p*p)
16737fad103SWill Pazner            d2d[1, :, :] = kron(b1d, d1d)
16837fad103SWill Pazner            d2d[2, :, :] = kron(d1d, b1d)
16937fad103SWill Pazner
17037fad103SWill Pazner            dim2 = 2
17137fad103SWill Pazner            b2 = create_tensor_h1_basis(c, dim2, 1, p, q, b1d, d1d, q1d, w1d)
17237fad103SWill Pazner            @test getinterp(b2) == kron(b1d, b1d)
17337fad103SWill Pazner            @test getinterp1d(b2) == b1d
17437fad103SWill Pazner            @test getgrad(b2) == d2d
17537fad103SWill Pazner            @test getgrad1d(b2) == d1d
17637fad103SWill Pazner
177b2e3f8ecSSebastian Grimberg            b3 = create_h1_basis(
178b2e3f8ecSSebastian Grimberg                c,
179b2e3f8ecSSebastian Grimberg                LINE,
180b2e3f8ecSSebastian Grimberg                1,
181b2e3f8ecSSebastian Grimberg                p,
182b2e3f8ecSSebastian Grimberg                q,
183b2e3f8ecSSebastian Grimberg                b1d,
184b2e3f8ecSSebastian Grimberg                reshape(d1d, 1, q, p),
185b2e3f8ecSSebastian Grimberg                reshape(q1d, 1, q),
186b2e3f8ecSSebastian Grimberg                w1d,
187b2e3f8ecSSebastian Grimberg            )
188b2e3f8ecSSebastian Grimberg            @test getqref(b3) == reshape(q1d, 1, q)
18937fad103SWill Pazner            @test getqweights(b3) == w1d
19037fad103SWill Pazner
19180a9ef05SNatalie Beams            v = rand(CeedScalar, 2)
19237fad103SWill Pazner            vq = apply(b3, v)
19337fad103SWill Pazner            vd = apply(b3, v; emode=EVAL_GRAD)
19437fad103SWill Pazner            @test vq ≈ b1d*v
19537fad103SWill Pazner            @test vd ≈ d1d*v
19637fad103SWill Pazner        end
19737fad103SWill Pazner
19837fad103SWill Pazner        @testset "Request" begin
19937fad103SWill Pazner            @test RequestImmediate()[] == LibCEED.C.CEED_REQUEST_IMMEDIATE[]
20037fad103SWill Pazner            @test RequestOrdered()[] == LibCEED.C.CEED_REQUEST_ORDERED[]
20137fad103SWill Pazner        end
20237fad103SWill Pazner
20337fad103SWill Pazner        @testset "Misc" begin
20437fad103SWill Pazner            for dim = 1:3
20537fad103SWill Pazner                D = CeedDim(dim)
20680a9ef05SNatalie Beams                J = rand(CeedScalar, dim, dim)
20737fad103SWill Pazner                @test det(J, D) ≈ det(J)
20837fad103SWill Pazner                J = J + J' # make symmetric
20937fad103SWill Pazner                @test setvoigt(SMatrix{dim,dim}(J)) == setvoigt(J, D)
21037fad103SWill Pazner                @test getvoigt(setvoigt(J, D)) == J
21180a9ef05SNatalie Beams                V = zeros(CeedScalar, dim*(dim + 1)÷2)
21237fad103SWill Pazner                setvoigt!(V, J, D)
21337fad103SWill Pazner                @test V == setvoigt(J, D)
21480a9ef05SNatalie Beams                J2 = zeros(CeedScalar, dim, dim)
21537fad103SWill Pazner                getvoigt!(J2, V, D)
21637fad103SWill Pazner                @test J2 == J
21737fad103SWill Pazner            end
21837fad103SWill Pazner        end
21937fad103SWill Pazner
22037fad103SWill Pazner        @testset "Operator" begin
22137fad103SWill Pazner            c = Ceed()
22237fad103SWill Pazner            @interior_qf id = (
22337fad103SWill Pazner                c,
22437fad103SWill Pazner                (input, :in, EVAL_INTERP),
22537fad103SWill Pazner                (output, :out, EVAL_INTERP),
22637fad103SWill Pazner                begin
22737fad103SWill Pazner                    output[] = input
22837fad103SWill Pazner                end,
22937fad103SWill Pazner            )
23037fad103SWill Pazner            b = create_tensor_h1_lagrange_basis(c, 3, 1, 3, 3, GAUSS_LOBATTO)
23137fad103SWill Pazner            n = getnumnodes(b)
23237fad103SWill Pazner            offsets = Vector{CeedInt}(0:n-1)
23337fad103SWill Pazner            r = create_elem_restriction(c, 1, n, 1, 1, n, offsets)
23437fad103SWill Pazner            op = Operator(
23537fad103SWill Pazner                c;
23637fad103SWill Pazner                qf=id,
23737fad103SWill Pazner                fields=[
23837fad103SWill Pazner                    (:input, r, b, CeedVectorActive()),
23937fad103SWill Pazner                    (:output, r, b, CeedVectorActive()),
24037fad103SWill Pazner                ],
24137fad103SWill Pazner            )
24237fad103SWill Pazner
24380a9ef05SNatalie Beams            v = rand(CeedScalar, n)
24437fad103SWill Pazner            v1 = CeedVector(c, v)
24537fad103SWill Pazner            v2 = CeedVector(c, n)
24637fad103SWill Pazner            apply!(op, v1, v2)
24737fad103SWill Pazner            @test @witharray_read(a1 = v1, @witharray_read(a2 = v2, a1 == a2))
24837fad103SWill Pazner            apply_add!(op, v1, v2)
24937fad103SWill Pazner            @test @witharray_read(a1 = v1, @witharray_read(a2 = v2, a1 + a1 == a2))
25037fad103SWill Pazner
25137fad103SWill Pazner            diag_vector = create_lvector(r)
25237fad103SWill Pazner            LibCEED.assemble_diagonal!(op, diag_vector)
25337fad103SWill Pazner            @test @witharray_read(a = diag_vector, a == ones(n))
25437fad103SWill Pazner            # TODO: change this test after bug-fix in libCEED
25537fad103SWill Pazner            diag_vector[] = 0.0
25637fad103SWill Pazner            LibCEED.assemble_add_diagonal!(op, diag_vector)
25737fad103SWill Pazner            @test @witharray(a = diag_vector, a == fill(1.0, n))
25837fad103SWill Pazner
25937fad103SWill Pazner            comp_op = create_composite_operator(c, [op])
26037fad103SWill Pazner            apply!(comp_op, v1, v2)
26137fad103SWill Pazner            @test @witharray_read(a1 = v1, @witharray_read(a2 = v2, a1 == a2))
262bd9c22baSWill Pazner
263bd9c22baSWill Pazner            @test showstr(op) == """
264bd9c22baSWill Pazner                CeedOperator
265bd9c22baSWill Pazner                  1 elements with 27 quadrature points each
266bd9c22baSWill Pazner                  2 fields
267bd9c22baSWill Pazner                  1 input field:
268bd9c22baSWill Pazner                    Input field 0:
269bd9c22baSWill Pazner                      Name: "input"
270bd9c22baSWill Pazner                      Size: 1
271bd9c22baSWill Pazner                      EvalMode: interpolation
272bd9c22baSWill Pazner                      Active vector
273bd9c22baSWill Pazner                  1 output field:
274bd9c22baSWill Pazner                    Output field 0:
275bd9c22baSWill Pazner                      Name: "output"
276bd9c22baSWill Pazner                      Size: 1
277bd9c22baSWill Pazner                      EvalMode: interpolation
278bd9c22baSWill Pazner                      Active vector"""
27937fad103SWill Pazner        end
28037fad103SWill Pazner
28137fad103SWill Pazner        @testset "ElemRestriction" begin
28237fad103SWill Pazner            c = Ceed()
28337fad103SWill Pazner            n = 10
28437fad103SWill Pazner            offsets = Vector{CeedInt}([0:n-1; n-1:2*n-2])
28537fad103SWill Pazner            lsize = 2*n - 1
28637fad103SWill Pazner            r = create_elem_restriction(c, 2, n, 1, lsize, lsize, offsets)
28737fad103SWill Pazner            @test getcompstride(r) == lsize
28837fad103SWill Pazner            @test getnumelements(r) == 2
28937fad103SWill Pazner            @test getelementsize(r) == n
29037fad103SWill Pazner            @test getlvectorsize(r) == lsize
29137fad103SWill Pazner            @test getnumcomponents(r) == 1
29237fad103SWill Pazner            @test length(create_lvector(r)) == lsize
29337fad103SWill Pazner            @test length(create_evector(r)) == 2*n
29437fad103SWill Pazner            lv, ev = create_vectors(r)
29537fad103SWill Pazner            @test length(lv) == lsize
29637fad103SWill Pazner            @test length(ev) == 2*n
29737fad103SWill Pazner            mult = getmultiplicity(r)
29837fad103SWill Pazner            mult2 = ones(lsize)
29937fad103SWill Pazner            mult2[n] = 2
30037fad103SWill Pazner            @test mult == mult2
30180a9ef05SNatalie Beams            rand_lv = rand(CeedScalar, lsize)
30237fad103SWill Pazner            rand_ev = [rand_lv[1:n]; rand_lv[n:end]]
30337fad103SWill Pazner            @test apply(r, rand_lv) == rand_ev
30437fad103SWill Pazner            @test apply(r, rand_ev; tmode=TRANSPOSE) == rand_lv.*mult
30537fad103SWill Pazner            @test showstr(r) == string(
30637fad103SWill Pazner                "CeedElemRestriction from (19, 1) to 2 elements ",
30737fad103SWill Pazner                "with 10 nodes each and component stride 19",
30837fad103SWill Pazner            )
30937fad103SWill Pazner
31037fad103SWill Pazner            strides = CeedInt[1, n, n]
31137fad103SWill Pazner            rs = create_elem_restriction_strided(c, 1, n, 1, n, strides)
31237fad103SWill Pazner            @test showstr(rs) == string(
31337fad103SWill Pazner                "CeedElemRestriction from (10, 1) to 1 elements ",
31437fad103SWill Pazner                "with 10 nodes each and strides [1, $n, $n]",
31537fad103SWill Pazner            )
31637fad103SWill Pazner
31737fad103SWill Pazner            @test ElemRestrictionNone()[] == LibCEED.C.CEED_ELEMRESTRICTION_NONE[]
31837fad103SWill Pazner        end
319bd9c22baSWill Pazner
320bd9c22baSWill Pazner        @testset "QFunction" begin
321bd9c22baSWill Pazner            c = Ceed()
322bd9c22baSWill Pazner            @test showstr(create_interior_qfunction(c, "Poisson3DApply")) == """
323bd9c22baSWill Pazner                 Gallery CeedQFunction - Poisson3DApply
324bd9c22baSWill Pazner                   2 input fields:
325bd9c22baSWill Pazner                     Input field 0:
326bd9c22baSWill Pazner                       Name: "du"
327bd9c22baSWill Pazner                       Size: 3
328bd9c22baSWill Pazner                       EvalMode: "gradient"
329bd9c22baSWill Pazner                     Input field 1:
330bd9c22baSWill Pazner                       Name: "qdata"
331bd9c22baSWill Pazner                       Size: 6
332bd9c22baSWill Pazner                       EvalMode: "none"
333bd9c22baSWill Pazner                   1 output field:
334bd9c22baSWill Pazner                     Output field 0:
335bd9c22baSWill Pazner                       Name: "dv"
336bd9c22baSWill Pazner                       Size: 3
337bd9c22baSWill Pazner                       EvalMode: "gradient\""""
338bd9c22baSWill Pazner
339bd9c22baSWill Pazner            id = create_identity_qfunction(c, 1, EVAL_INTERP, EVAL_INTERP)
340bd9c22baSWill Pazner            Q = 10
341bd9c22baSWill Pazner            v = rand(CeedScalar, Q)
342bd9c22baSWill Pazner            v1 = CeedVector(c, v)
343bd9c22baSWill Pazner            v2 = CeedVector(c, Q)
344bd9c22baSWill Pazner            apply!(id, Q, [v1], [v2])
345bd9c22baSWill Pazner            @test @witharray(a = v2, a == v)
346bd9c22baSWill Pazner
347bd9c22baSWill Pazner            @interior_qf id2 = (c, (a, :in, EVAL_INTERP), (b, :out, EVAL_INTERP), b .= a)
348bd9c22baSWill Pazner            v2[] = 0.0
349bd9c22baSWill Pazner            apply!(id2, Q, [v1], [v2])
350bd9c22baSWill Pazner            @test @witharray(a = v2, a == v)
351bd9c22baSWill Pazner
352bd9c22baSWill Pazner            ctxdata = CtxData(IOBuffer(), rand(CeedScalar, 3))
353bd9c22baSWill Pazner            ctx = Context(c, ctxdata)
354bd9c22baSWill Pazner            dim = 3
355bd9c22baSWill Pazner            @interior_qf qf = (
356bd9c22baSWill Pazner                c,
357bd9c22baSWill Pazner                dim=dim,
358bd9c22baSWill Pazner                ctxdata::CtxData,
359bd9c22baSWill Pazner                (a, :in, EVAL_GRAD, dim),
360bd9c22baSWill Pazner                (b, :in, EVAL_NONE),
361bd9c22baSWill Pazner                (c, :out, EVAL_INTERP),
362bd9c22baSWill Pazner                begin
363bd9c22baSWill Pazner                    c[] = b*sum(a)
364bd9c22baSWill Pazner                    show(ctxdata.io, MIME("text/plain"), ctxdata.x)
365bd9c22baSWill Pazner                end,
366bd9c22baSWill Pazner            )
367bd9c22baSWill Pazner            set_context!(qf, ctx)
368bd9c22baSWill Pazner            in_sz, out_sz = LibCEED.get_field_sizes(qf)
369bd9c22baSWill Pazner            @test in_sz == [dim, 1]
370bd9c22baSWill Pazner            @test out_sz == [1]
371bd9c22baSWill Pazner            v1 = rand(CeedScalar, dim)
372bd9c22baSWill Pazner            v2 = rand(CeedScalar, 1)
373bd9c22baSWill Pazner            cv1 = CeedVector(c, v1)
374bd9c22baSWill Pazner            cv2 = CeedVector(c, v2)
375bd9c22baSWill Pazner            cv3 = CeedVector(c, 1)
376bd9c22baSWill Pazner            apply!(qf, 1, [cv1, cv2], [cv3])
377bd9c22baSWill Pazner            @test String(take!(ctxdata.io)) == showstr(ctxdata.x)
378bd9c22baSWill Pazner            @test @witharray_read(v3 = cv3, v3[1] == v2[1]*sum(v1))
379bd9c22baSWill Pazner
380bd9c22baSWill Pazner            @test QFunctionNone()[] == LibCEED.C.CEED_QFUNCTION_NONE[]
381bd9c22baSWill Pazner        end
382*77bb289aSJed Brown        @testset "Basis" begin
383*77bb289aSJed Brown            @test BasisNone()[] == LibCEED.C.CEED_BASIS_NONE[]
384*77bb289aSJed Brown
385*77bb289aSJed Brown            c = Ceed()
386*77bb289aSJed Brown            dim = 3
387*77bb289aSJed Brown            ncomp = 1
388*77bb289aSJed Brown            p = 4
389*77bb289aSJed Brown            q = 6
390*77bb289aSJed Brown            b1 = create_tensor_h1_lagrange_basis(c, dim, ncomp, p, q, GAUSS_LOBATTO)
391*77bb289aSJed Brown
392*77bb289aSJed Brown            @test checkoutput(showstr(b1), "b1.out")
393*77bb289aSJed Brown
394*77bb289aSJed Brown            b1d = CeedScalar[1.0 0.0; 0.5 0.5; 0.0 1.0]
395*77bb289aSJed Brown            d1d = CeedScalar[-0.5 0.5; -0.5 0.5; -0.5 0.5]
396*77bb289aSJed Brown            q1d = CeedScalar[-1.0, 0.0, 1.0]
397*77bb289aSJed Brown            w1d = CeedScalar[1/3, 4/3, 1/3]
398*77bb289aSJed Brown            q, p = size(b1d)
399*77bb289aSJed Brown            d2d = zeros(CeedScalar, 2, q*q, p*p)
400*77bb289aSJed Brown            d2d[1, :, :] = kron(b1d, d1d)
401*77bb289aSJed Brown            d2d[2, :, :] = kron(d1d, b1d)
402*77bb289aSJed Brown
403*77bb289aSJed Brown            dim2 = 2
404*77bb289aSJed Brown            b2 = create_tensor_h1_basis(c, dim2, 1, p, q, b1d, d1d, q1d, w1d)
405*77bb289aSJed Brown            @test checkoutput(showstr(b2), "b2.out")
406*77bb289aSJed Brown
407*77bb289aSJed Brown            b3 = create_h1_basis(
408*77bb289aSJed Brown                c,
409*77bb289aSJed Brown                LINE,
410*77bb289aSJed Brown                1,
411*77bb289aSJed Brown                p,
412*77bb289aSJed Brown                q,
413*77bb289aSJed Brown                b1d,
414*77bb289aSJed Brown                reshape(d1d, 1, q, p),
415*77bb289aSJed Brown                reshape(q1d, 1, q),
416*77bb289aSJed Brown                w1d,
417*77bb289aSJed Brown            )
418*77bb289aSJed Brown            @test checkoutput(showstr(b3), "b3.out")
419*77bb289aSJed Brown
420*77bb289aSJed Brown            dim = 2
421*77bb289aSJed Brown            ncomp = 1
422*77bb289aSJed Brown            p1 = 4
423*77bb289aSJed Brown            q1 = 4
424*77bb289aSJed Brown            qref1 = Array{Float64}(undef, dim, q1)
425*77bb289aSJed Brown            qweight1 = Array{Float64}(undef, q1)
426*77bb289aSJed Brown            interp1, div1 = build_mats_hdiv(qref1, qweight1)
427*77bb289aSJed Brown            b1 = create_hdiv_basis(c, QUAD, ncomp, p1, q1, interp1, div1, qref1, qweight1)
428*77bb289aSJed Brown
429*77bb289aSJed Brown            u1 = ones(Float64, p1)
430*77bb289aSJed Brown            v1 = apply(b1, u1)
431*77bb289aSJed Brown
432*77bb289aSJed Brown            for i = 1:q1
433*77bb289aSJed Brown                @test v1[i] ≈ -1.0
434*77bb289aSJed Brown                @test v1[q1+i] ≈ 1.0
435*77bb289aSJed Brown            end
436*77bb289aSJed Brown
437*77bb289aSJed Brown            p2 = 3
438*77bb289aSJed Brown            q2 = 4
439*77bb289aSJed Brown            qref2 = Array{Float64}(undef, dim, q2)
440*77bb289aSJed Brown            qweight2 = Array{Float64}(undef, q2)
441*77bb289aSJed Brown            interp2, curl2 = build_mats_hcurl(qref2, qweight2)
442*77bb289aSJed Brown            b2 = create_hcurl_basis(
443*77bb289aSJed Brown                c,
444*77bb289aSJed Brown                TRIANGLE,
445*77bb289aSJed Brown                ncomp,
446*77bb289aSJed Brown                p2,
447*77bb289aSJed Brown                q2,
448*77bb289aSJed Brown                interp2,
449*77bb289aSJed Brown                curl2,
450*77bb289aSJed Brown                qref2,
451*77bb289aSJed Brown                qweight2,
452*77bb289aSJed Brown            )
453*77bb289aSJed Brown
454*77bb289aSJed Brown            u2 = [1.0, 2.0, 1.0]
455*77bb289aSJed Brown            v2 = apply(b2, u2)
456*77bb289aSJed Brown
457*77bb289aSJed Brown            for i = 1:q2
458*77bb289aSJed Brown                @test v2[i] ≈ 1.0
459*77bb289aSJed Brown            end
460*77bb289aSJed Brown
461*77bb289aSJed Brown            u2[1] = -1.0
462*77bb289aSJed Brown            u2[2] = 1.0
463*77bb289aSJed Brown            u2[3] = 2.0
464*77bb289aSJed Brown            v2 = apply(b2, u2)
465*77bb289aSJed Brown
466*77bb289aSJed Brown            for i = 1:q2
467*77bb289aSJed Brown                @test v2[q2+i] ≈ 1.0
468*77bb289aSJed Brown            end
469*77bb289aSJed Brown        end
470*77bb289aSJed Brown
471*77bb289aSJed Brown        @testset "ElemRestriction" begin
472*77bb289aSJed Brown            c = Ceed()
473*77bb289aSJed Brown            nelem = 3
474*77bb289aSJed Brown            elemsize = 2
475*77bb289aSJed Brown            offsets = Array{CeedInt}(undef, elemsize, nelem)
476*77bb289aSJed Brown            orients = Array{Bool}(undef, elemsize, nelem)
477*77bb289aSJed Brown            for i = 1:nelem
478*77bb289aSJed Brown                offsets[1, i] = i - 1
479*77bb289aSJed Brown                offsets[2, i] = i
480*77bb289aSJed Brown                # flip the dofs on element 1, 3, ...
481*77bb289aSJed Brown                orients[1, i] = (i - 1)%2 > 0
482*77bb289aSJed Brown                orients[2, i] = (i - 1)%2 > 0
483*77bb289aSJed Brown            end
484*77bb289aSJed Brown            r = create_elem_restriction_oriented(
485*77bb289aSJed Brown                c,
486*77bb289aSJed Brown                nelem,
487*77bb289aSJed Brown                elemsize,
488*77bb289aSJed Brown                1,
489*77bb289aSJed Brown                1,
490*77bb289aSJed Brown                nelem + 1,
491*77bb289aSJed Brown                offsets,
492*77bb289aSJed Brown                orients,
493*77bb289aSJed Brown            )
494*77bb289aSJed Brown
495*77bb289aSJed Brown            lv = Vector{CeedScalar}(undef, nelem + 1)
496*77bb289aSJed Brown            for i = 1:nelem+1
497*77bb289aSJed Brown                lv[i] = 10 + i - 1
498*77bb289aSJed Brown            end
499*77bb289aSJed Brown
500*77bb289aSJed Brown            ev = apply(r, lv)
501*77bb289aSJed Brown
502*77bb289aSJed Brown            for i = 1:nelem
503*77bb289aSJed Brown                for j = 1:elemsize
504*77bb289aSJed Brown                    k = j + elemsize*(i - 1)
505*77bb289aSJed Brown                    @test 10 + k÷2 == ev[k]*(-1)^((i - 1)%2)
506*77bb289aSJed Brown                end
507*77bb289aSJed Brown            end
508*77bb289aSJed Brown
509*77bb289aSJed Brown            curlorients = Array{CeedInt8}(undef, 3*elemsize, nelem)
510*77bb289aSJed Brown            for i = 1:nelem
511*77bb289aSJed Brown                curlorients[1, i] = curlorients[6, i] = 0
512*77bb289aSJed Brown                if (i - 1)%2 > 0
513*77bb289aSJed Brown                    # T = [0  -1]
514*77bb289aSJed Brown                    #     [-1  0]
515*77bb289aSJed Brown                    curlorients[2, i] = 0
516*77bb289aSJed Brown                    curlorients[3, i] = -1
517*77bb289aSJed Brown                    curlorients[4, i] = -1
518*77bb289aSJed Brown                    curlorients[5, i] = 0
519*77bb289aSJed Brown                else
520*77bb289aSJed Brown                    # T = I
521*77bb289aSJed Brown                    curlorients[2, i] = 1
522*77bb289aSJed Brown                    curlorients[3, i] = 0
523*77bb289aSJed Brown                    curlorients[4, i] = 0
524*77bb289aSJed Brown                    curlorients[5, i] = 1
525*77bb289aSJed Brown                end
526*77bb289aSJed Brown            end
527*77bb289aSJed Brown            r = create_elem_restriction_curl_oriented(
528*77bb289aSJed Brown                c,
529*77bb289aSJed Brown                nelem,
530*77bb289aSJed Brown                elemsize,
531*77bb289aSJed Brown                1,
532*77bb289aSJed Brown                1,
533*77bb289aSJed Brown                nelem + 1,
534*77bb289aSJed Brown                offsets,
535*77bb289aSJed Brown                curlorients,
536*77bb289aSJed Brown            )
537*77bb289aSJed Brown
538*77bb289aSJed Brown            ev = apply(r, lv)
539*77bb289aSJed Brown
540*77bb289aSJed Brown            for i = 1:nelem
541*77bb289aSJed Brown                for j = 1:elemsize
542*77bb289aSJed Brown                    k = j + elemsize*(i - 1)
543*77bb289aSJed Brown                    if (i - 1)%2 > 0
544*77bb289aSJed Brown                        @test j == 2 || 10 + i == -ev[k]
545*77bb289aSJed Brown                        @test j == 1 || 10 + i - 1 == -ev[k]
546*77bb289aSJed Brown                    else
547*77bb289aSJed Brown                        @test 10 + k÷2 == ev[k]
548*77bb289aSJed Brown                    end
549*77bb289aSJed Brown                end
550*77bb289aSJed Brown            end
551*77bb289aSJed Brown        end
55237fad103SWill Pazner    end
553f99607bdSWill Paznerend
554