xref: /libCEED/julia/LibCEED.jl/test/runtests.jl (revision a697ff736c4bbf0dcf3b0c0690ba5a6b92dd6bdf)
137fad103SWill Paznerusing Test, LibCEED, LinearAlgebra, StaticArrays
237fad103SWill Pazner
337fad103SWill Paznerfunction iostr(f, x)
437fad103SWill Pazner    io = IOBuffer()
537fad103SWill Pazner    f(io, x)
637fad103SWill Pazner    String(take!(io))
737fad103SWill Paznerend
837fad103SWill Paznerfunction showstr(x)
937fad103SWill Pazner    iostr(x) do io, y
1037fad103SWill Pazner        show(io, MIME("text/plain"), y)
1137fad103SWill Pazner    end
1237fad103SWill Paznerend
1337fad103SWill Paznersummarystr(x) = iostr(summary, x)
1437fad103SWill Paznergetoutput(fname) = chomp(read(joinpath(@__DIR__, "output", fname), String))
1537fad103SWill Pazner
1637fad103SWill Paznermutable struct CtxData
1737fad103SWill Pazner    io::IOBuffer
1837fad103SWill Pazner    x::Vector{Float64}
1937fad103SWill Paznerend
2037fad103SWill Pazner
21*a697ff73SWill Paznerif "--run-dev-tests" in ARGS
22*a697ff73SWill Pazner    include("rundevtests.jl")
23*a697ff73SWill Paznerend
24*a697ff73SWill Pazner
25*a697ff73SWill Pazner@testset "LibCEED Release Tests" begin
2637fad103SWill Pazner    @testset "Ceed" begin
2737fad103SWill Pazner        res = "/cpu/self/ref/serial"
2837fad103SWill Pazner        c = Ceed(res)
2937fad103SWill Pazner        @test isdeterministic(c)
3037fad103SWill Pazner        @test getresource(c) == res
3137fad103SWill Pazner        @test !iscuda(c)
3237fad103SWill Pazner        @test get_preferred_memtype(c) == MEM_HOST
3337fad103SWill Pazner        @test_throws LibCEED.CeedError create_interior_qfunction(c, "")
3437fad103SWill Pazner        @test showstr(c) == """
3537fad103SWill Pazner            Ceed
3637fad103SWill Pazner              Ceed Resource: $res
3737fad103SWill Pazner              Preferred MemType: host"""
3837fad103SWill Pazner    end
3937fad103SWill Pazner
4037fad103SWill Pazner    @testset "Context" begin
4137fad103SWill Pazner        c = Ceed()
4237fad103SWill Pazner        data = zeros(3)
4337fad103SWill Pazner        ctx = Context(c, data)
4437fad103SWill Pazner        @test showstr(ctx) == """
4537fad103SWill Pazner            CeedQFunctionContext
4637fad103SWill Pazner              Context Data Size: $(sizeof(data))"""
4737fad103SWill Pazner        @test_throws Exception set_data!(ctx, MEM_HOST, OWN_POINTER, data)
4837fad103SWill Pazner    end
4937fad103SWill Pazner
5037fad103SWill Pazner    @testset "CeedVector" begin
5137fad103SWill Pazner        n = 10
5237fad103SWill Pazner        c = Ceed()
5337fad103SWill Pazner        v = CeedVector(c, n)
5437fad103SWill Pazner        @test size(v) == (n,)
5537fad103SWill Pazner        @test length(v) == n
5637fad103SWill Pazner        @test axes(v) == (1:n,)
5737fad103SWill Pazner        @test ndims(v) == 1
5837fad103SWill Pazner        @test ndims(CeedVector) == 1
5937fad103SWill Pazner
6037fad103SWill Pazner        v[] = 0.0
6137fad103SWill Pazner        @test @witharray(a = v, all(a .== 0.0))
6237fad103SWill Pazner
6337fad103SWill Pazner        v1 = rand(n)
6437fad103SWill Pazner        v2 = CeedVector(c, v1)
6537fad103SWill Pazner        @test @witharray_read(a = v2, mtype = MEM_HOST, a == v1)
6637fad103SWill Pazner        @test Vector(v2) == v1
6737fad103SWill Pazner        v[] = v1
6837fad103SWill Pazner        for p ∈ [1, 2, Inf]
6937fad103SWill Pazner            @test norm(v, p) ≈ norm(v1, p)
7037fad103SWill Pazner        end
7137fad103SWill Pazner        @test_throws Exception norm(v, 3)
7237fad103SWill Pazner        @test witharray_read(sum, v) == sum(v1)
7337fad103SWill Pazner        reciprocal!(v)
7437fad103SWill Pazner        @test @witharray(a = v, mtype = MEM_HOST, all(a .== 1.0 ./ v1))
7537fad103SWill Pazner
7637fad103SWill Pazner        witharray(x -> x .= 1.0, v)
7737fad103SWill Pazner        @test @witharray(a = v, all(a .== 1.0))
7837fad103SWill Pazner
7937fad103SWill Pazner        @test summarystr(v) == "$n-element CeedVector"
8037fad103SWill Pazner        @test iostr(show, v) == @witharray_read(a = v, iostr(show, a))
8137fad103SWill Pazner        io = IOBuffer()
8237fad103SWill Pazner        summary(io, v)
8337fad103SWill Pazner        println(io, ":")
8437fad103SWill Pazner        @witharray_read(a = v, Base.print_array(io, a))
8537fad103SWill Pazner        s1 = String(take!(io))
8637fad103SWill Pazner        @test showstr(v) == s1
8737fad103SWill Pazner
8837fad103SWill Pazner        setarray!(v, MEM_HOST, USE_POINTER, v1)
8937fad103SWill Pazner        syncarray!(v, MEM_HOST)
9037fad103SWill Pazner        @test @witharray_read(a = v, a == v1)
9137fad103SWill Pazner        p = takearray!(v, MEM_HOST)
9237fad103SWill Pazner        @test p == pointer(v1)
9337fad103SWill Pazner
9437fad103SWill Pazner        m = rand(10, 10)
9537fad103SWill Pazner        vm = CeedVector(c, vec(m))
9637fad103SWill Pazner        @test @witharray_read(a = vm, size = size(m), a == m)
9737fad103SWill Pazner
9837fad103SWill Pazner        @test CeedVectorActive()[] == LibCEED.C.CEED_VECTOR_ACTIVE[]
9937fad103SWill Pazner        @test CeedVectorNone()[] == LibCEED.C.CEED_VECTOR_NONE[]
10037fad103SWill Pazner    end
10137fad103SWill Pazner
10237fad103SWill Pazner    @testset "Basis" begin
10337fad103SWill Pazner        c = Ceed()
10437fad103SWill Pazner        dim = 3
10537fad103SWill Pazner        ncomp = 1
10637fad103SWill Pazner        p = 4
10737fad103SWill Pazner        q = 6
10837fad103SWill Pazner        b1 = create_tensor_h1_lagrange_basis(c, dim, ncomp, p, q, GAUSS_LOBATTO)
10937fad103SWill Pazner
11037fad103SWill Pazner        @test showstr(b1) == getoutput("b1.out")
11137fad103SWill Pazner        @test getdimension(b1) == 3
11237fad103SWill Pazner        @test gettopology(b1) == HEX
11337fad103SWill Pazner        @test getnumcomponents(b1) == ncomp
11437fad103SWill Pazner        @test getnumnodes(b1) == p^dim
11537fad103SWill Pazner        @test getnumnodes1d(b1) == p
11637fad103SWill Pazner        @test getnumqpts(b1) == q^dim
11737fad103SWill Pazner        @test getnumqpts1d(b1) == q
11837fad103SWill Pazner
11937fad103SWill Pazner        q1d, w1d = lobatto_quadrature(3, AbscissaAndWeights)
12037fad103SWill Pazner        @test q1d ≈ [-1.0, 0.0, 1.0]
12137fad103SWill Pazner        @test w1d ≈ [1/3, 4/3, 1/3]
12237fad103SWill Pazner
12337fad103SWill Pazner        q1d, w1d = gauss_quadrature(3)
12437fad103SWill Pazner        @test q1d ≈ [-sqrt(3/5), 0.0, sqrt(3/5)]
12537fad103SWill Pazner        @test w1d ≈ [5/9, 8/9, 5/9]
12637fad103SWill Pazner
12737fad103SWill Pazner        b1d = [1.0 0.0; 0.5 0.5; 0.0 1.0]
12837fad103SWill Pazner        d1d = [-0.5 0.5; -0.5 0.5; -0.5 0.5]
12937fad103SWill Pazner        q1d = [-1.0, 0.0, 1.0]
13037fad103SWill Pazner        w1d = [1/3, 4/3, 1/3]
13137fad103SWill Pazner        q, p = size(b1d)
13237fad103SWill Pazner        d2d = zeros(2, q*q, p*p)
13337fad103SWill Pazner        d2d[1, :, :] = kron(b1d, d1d)
13437fad103SWill Pazner        d2d[2, :, :] = kron(d1d, b1d)
13537fad103SWill Pazner
13637fad103SWill Pazner        dim2 = 2
13737fad103SWill Pazner        b2 = create_tensor_h1_basis(c, dim2, 1, p, q, b1d, d1d, q1d, w1d)
13837fad103SWill Pazner        @test getinterp(b2) == kron(b1d, b1d)
13937fad103SWill Pazner        @test getinterp1d(b2) == b1d
14037fad103SWill Pazner        @test getgrad(b2) == d2d
14137fad103SWill Pazner        @test getgrad1d(b2) == d1d
14237fad103SWill Pazner        @test showstr(b2) == getoutput("b2.out")
14337fad103SWill Pazner
14437fad103SWill Pazner        b3 = create_h1_basis(c, LINE, 1, p, q, b1d, reshape(d1d, 1, q, p), q1d, w1d)
14537fad103SWill Pazner        @test getqref(b3) == q1d
14637fad103SWill Pazner        @test getqweights(b3) == w1d
14737fad103SWill Pazner        @test showstr(b3) == getoutput("b3.out")
14837fad103SWill Pazner
14937fad103SWill Pazner        v = rand(2)
15037fad103SWill Pazner        vq = apply(b3, v)
15137fad103SWill Pazner        vd = apply(b3, v; emode=EVAL_GRAD)
15237fad103SWill Pazner        @test vq ≈ b1d*v
15337fad103SWill Pazner        @test vd ≈ d1d*v
15437fad103SWill Pazner
15537fad103SWill Pazner        @test BasisCollocated()[] == LibCEED.C.CEED_BASIS_COLLOCATED[]
15637fad103SWill Pazner    end
15737fad103SWill Pazner
15837fad103SWill Pazner    @testset "Request" begin
15937fad103SWill Pazner        @test RequestImmediate()[] == LibCEED.C.CEED_REQUEST_IMMEDIATE[]
16037fad103SWill Pazner        @test RequestOrdered()[] == LibCEED.C.CEED_REQUEST_ORDERED[]
16137fad103SWill Pazner    end
16237fad103SWill Pazner
16337fad103SWill Pazner    @testset "Misc" begin
16437fad103SWill Pazner        for dim = 1:3
16537fad103SWill Pazner            D = CeedDim(dim)
16637fad103SWill Pazner            J = rand(dim, dim)
16737fad103SWill Pazner            @test det(J, D) ≈ det(J)
16837fad103SWill Pazner            J = J + J' # make symmetric
16937fad103SWill Pazner            @test setvoigt(SMatrix{dim,dim}(J)) == setvoigt(J, D)
17037fad103SWill Pazner            @test getvoigt(setvoigt(J, D)) == J
17137fad103SWill Pazner            V = zeros(dim*(dim + 1)÷2)
17237fad103SWill Pazner            setvoigt!(V, J, D)
17337fad103SWill Pazner            @test V == setvoigt(J, D)
17437fad103SWill Pazner            J2 = zeros(dim, dim)
17537fad103SWill Pazner            getvoigt!(J2, V, D)
17637fad103SWill Pazner            @test J2 == J
17737fad103SWill Pazner        end
17837fad103SWill Pazner    end
17937fad103SWill Pazner
18037fad103SWill Pazner    @testset "QFunction" begin
18137fad103SWill Pazner        c = Ceed()
18237fad103SWill Pazner
18337fad103SWill Pazner        id = create_identity_qfunction(c, 1, EVAL_INTERP, EVAL_INTERP)
18437fad103SWill Pazner        Q = 10
18537fad103SWill Pazner        v = rand(Q)
18637fad103SWill Pazner        v1 = CeedVector(c, v)
18737fad103SWill Pazner        v2 = CeedVector(c, Q)
18837fad103SWill Pazner        apply!(id, Q, [v1], [v2])
18937fad103SWill Pazner        @test @witharray(a = v2, a == v)
19037fad103SWill Pazner
19137fad103SWill Pazner        @test showstr(create_interior_qfunction(c, "Poisson3DApply")) == """
19237fad103SWill Pazner            Gallery CeedQFunction Poisson3DApply
19337fad103SWill Pazner              2 Input Fields:
19437fad103SWill Pazner                Input Field [0]:
19537fad103SWill Pazner                  Name: "du"
19637fad103SWill Pazner                  Size: 3
19737fad103SWill Pazner                  EvalMode: "gradient"
19837fad103SWill Pazner                Input Field [1]:
19937fad103SWill Pazner                  Name: "qdata"
20037fad103SWill Pazner                  Size: 6
20137fad103SWill Pazner                  EvalMode: "none"
20237fad103SWill Pazner              1 Output Field:
20337fad103SWill Pazner                Output Field [0]:
20437fad103SWill Pazner                  Name: "dv"
20537fad103SWill Pazner                  Size: 3
20637fad103SWill Pazner                  EvalMode: "gradient\""""
20737fad103SWill Pazner
20837fad103SWill Pazner        @interior_qf id2 = (c, (a, :in, EVAL_INTERP), (b, :out, EVAL_INTERP), b.=a)
20937fad103SWill Pazner        v2[] = 0.0
21037fad103SWill Pazner        apply!(id2, Q, [v1], [v2])
21137fad103SWill Pazner        @test @witharray(a = v2, a == v)
21237fad103SWill Pazner
21337fad103SWill Pazner        ctxdata = CtxData(IOBuffer(), rand(3))
21437fad103SWill Pazner        ctx = Context(c, ctxdata)
21537fad103SWill Pazner        dim = 3
21637fad103SWill Pazner        @interior_qf qf = (
21737fad103SWill Pazner            c,
21837fad103SWill Pazner            dim=dim,
21937fad103SWill Pazner            ctxdata::CtxData,
22037fad103SWill Pazner            (a, :in, EVAL_GRAD, dim),
22137fad103SWill Pazner            (b, :in, EVAL_NONE),
22237fad103SWill Pazner            (c, :out, EVAL_INTERP),
22337fad103SWill Pazner            begin
22437fad103SWill Pazner                c[] = b*sum(a)
22537fad103SWill Pazner                show(ctxdata.io, MIME("text/plain"), ctxdata.x)
22637fad103SWill Pazner            end,
22737fad103SWill Pazner        )
22837fad103SWill Pazner        set_context!(qf, ctx)
22937fad103SWill Pazner        in_sz, out_sz = LibCEED.get_field_sizes(qf)
23037fad103SWill Pazner        @test in_sz == [dim, 1]
23137fad103SWill Pazner        @test out_sz == [1]
23237fad103SWill Pazner        v1 = rand(dim)
23337fad103SWill Pazner        v2 = rand(1)
23437fad103SWill Pazner        cv1 = CeedVector(c, v1)
23537fad103SWill Pazner        cv2 = CeedVector(c, v2)
23637fad103SWill Pazner        cv3 = CeedVector(c, 1)
23737fad103SWill Pazner        apply!(qf, 1, [cv1, cv2], [cv3])
23837fad103SWill Pazner        @test String(take!(ctxdata.io)) == showstr(ctxdata.x)
23937fad103SWill Pazner        @test @witharray_read(v3 = cv3, v3[1] == v2[1]*sum(v1))
24037fad103SWill Pazner
24137fad103SWill Pazner        @test QFunctionNone()[] == LibCEED.C.CEED_QFUNCTION_NONE[]
24237fad103SWill Pazner    end
24337fad103SWill Pazner
24437fad103SWill Pazner    @testset "Operator" begin
24537fad103SWill Pazner        c = Ceed()
24637fad103SWill Pazner        @interior_qf id = (
24737fad103SWill Pazner            c,
24837fad103SWill Pazner            (input, :in, EVAL_INTERP),
24937fad103SWill Pazner            (output, :out, EVAL_INTERP),
25037fad103SWill Pazner            begin
25137fad103SWill Pazner                output[] = input
25237fad103SWill Pazner            end,
25337fad103SWill Pazner        )
25437fad103SWill Pazner        b = create_tensor_h1_lagrange_basis(c, 3, 1, 3, 3, GAUSS_LOBATTO)
25537fad103SWill Pazner        n = getnumnodes(b)
25637fad103SWill Pazner        offsets = Vector{CeedInt}(0:n-1)
25737fad103SWill Pazner        r = create_elem_restriction(c, 1, n, 1, 1, n, offsets)
25837fad103SWill Pazner        op = Operator(
25937fad103SWill Pazner            c;
26037fad103SWill Pazner            qf=id,
26137fad103SWill Pazner            fields=[
26237fad103SWill Pazner                (:input, r, b, CeedVectorActive()),
26337fad103SWill Pazner                (:output, r, b, CeedVectorActive()),
26437fad103SWill Pazner            ],
26537fad103SWill Pazner        )
26637fad103SWill Pazner        @test showstr(op) == """
26737fad103SWill Pazner            CeedOperator
26837fad103SWill Pazner              2 Fields
26937fad103SWill Pazner              1 Input Field:
27037fad103SWill Pazner                Input Field [0]:
27137fad103SWill Pazner                  Name: "input"
27237fad103SWill Pazner                  Active vector
27337fad103SWill Pazner              1 Output Field:
27437fad103SWill Pazner                Output Field [0]:
27537fad103SWill Pazner                  Name: "output"
27637fad103SWill Pazner                  Active vector"""
27737fad103SWill Pazner
27837fad103SWill Pazner        v = rand(n)
27937fad103SWill Pazner        v1 = CeedVector(c, v)
28037fad103SWill Pazner        v2 = CeedVector(c, n)
28137fad103SWill Pazner        apply!(op, v1, v2)
28237fad103SWill Pazner        @test @witharray_read(a1 = v1, @witharray_read(a2 = v2, a1 == a2))
28337fad103SWill Pazner        apply_add!(op, v1, v2)
28437fad103SWill Pazner        @test @witharray_read(a1 = v1, @witharray_read(a2 = v2, a1 + a1 == a2))
28537fad103SWill Pazner
28637fad103SWill Pazner        diag_vector = create_lvector(r)
28737fad103SWill Pazner        LibCEED.assemble_diagonal!(op, diag_vector)
28837fad103SWill Pazner        @test @witharray_read(a = diag_vector, a == ones(n))
28937fad103SWill Pazner        # TODO: change this test after bug-fix in libCEED
29037fad103SWill Pazner        diag_vector[] = 0.0
29137fad103SWill Pazner        LibCEED.assemble_add_diagonal!(op, diag_vector)
29237fad103SWill Pazner        @test @witharray(a = diag_vector, a == fill(1.0, n))
29337fad103SWill Pazner
29437fad103SWill Pazner        comp_op = create_composite_operator(c, [op])
29537fad103SWill Pazner        apply!(comp_op, v1, v2)
29637fad103SWill Pazner        @test @witharray_read(a1 = v1, @witharray_read(a2 = v2, a1 == a2))
29737fad103SWill Pazner    end
29837fad103SWill Pazner
29937fad103SWill Pazner    @testset "ElemRestriction" begin
30037fad103SWill Pazner        c = Ceed()
30137fad103SWill Pazner        n = 10
30237fad103SWill Pazner        offsets = Vector{CeedInt}([0:n-1; n-1:2*n-2])
30337fad103SWill Pazner        lsize = 2*n - 1
30437fad103SWill Pazner        r = create_elem_restriction(c, 2, n, 1, lsize, lsize, offsets)
30537fad103SWill Pazner        @test getcompstride(r) == lsize
30637fad103SWill Pazner        @test getnumelements(r) == 2
30737fad103SWill Pazner        @test getelementsize(r) == n
30837fad103SWill Pazner        @test getlvectorsize(r) == lsize
30937fad103SWill Pazner        @test getnumcomponents(r) == 1
31037fad103SWill Pazner        @test length(create_lvector(r)) == lsize
31137fad103SWill Pazner        @test length(create_evector(r)) == 2*n
31237fad103SWill Pazner        lv, ev = create_vectors(r)
31337fad103SWill Pazner        @test length(lv) == lsize
31437fad103SWill Pazner        @test length(ev) == 2*n
31537fad103SWill Pazner        mult = getmultiplicity(r)
31637fad103SWill Pazner        mult2 = ones(lsize)
31737fad103SWill Pazner        mult2[n] = 2
31837fad103SWill Pazner        @test mult == mult2
31937fad103SWill Pazner        rand_lv = rand(lsize)
32037fad103SWill Pazner        rand_ev = [rand_lv[1:n]; rand_lv[n:end]]
32137fad103SWill Pazner        @test apply(r, rand_lv) == rand_ev
32237fad103SWill Pazner        @test apply(r, rand_ev; tmode=TRANSPOSE) == rand_lv.*mult
32337fad103SWill Pazner        @test showstr(r) == string(
32437fad103SWill Pazner            "CeedElemRestriction from (19, 1) to 2 elements ",
32537fad103SWill Pazner            "with 10 nodes each and component stride 19",
32637fad103SWill Pazner        )
32737fad103SWill Pazner
32837fad103SWill Pazner        strides = CeedInt[1, n, n]
32937fad103SWill Pazner        rs = create_elem_restriction_strided(c, 1, n, 1, n, strides)
33037fad103SWill Pazner        @test showstr(rs) == string(
33137fad103SWill Pazner            "CeedElemRestriction from (10, 1) to 1 elements ",
33237fad103SWill Pazner            "with 10 nodes each and strides [1, $n, $n]",
33337fad103SWill Pazner        )
33437fad103SWill Pazner
33537fad103SWill Pazner        @test ElemRestrictionNone()[] == LibCEED.C.CEED_ELEMRESTRICTION_NONE[]
33637fad103SWill Pazner    end
33737fad103SWill Paznerend
338