xref: /libCEED/julia/LibCEED.jl/examples/common.jl (revision 6cf3b68d14a6585b72105699d8534a500a16d388)
1*6cf3b68dSWill Paznerfunction get_cartesian_mesh_size(dim, order, prob_size)
2*6cf3b68dSWill Pazner    dims = zeros(CeedInt, dim)
3*6cf3b68dSWill Pazner    # Use the approximate formula:
4*6cf3b68dSWill Pazner    #    prob_size ~ num_elem * order^dim
5*6cf3b68dSWill Pazner    num_elem = div(prob_size, order^dim)
6*6cf3b68dSWill Pazner    s = 0 # find s: num_elem/2 < 2^s <= num_elem
7*6cf3b68dSWill Pazner    while num_elem > 1
8*6cf3b68dSWill Pazner        num_elem = div(num_elem, 2)
9*6cf3b68dSWill Pazner        s += 1
10*6cf3b68dSWill Pazner    end
11*6cf3b68dSWill Pazner    r = s%dim
12*6cf3b68dSWill Pazner    for d = 1:dim
13*6cf3b68dSWill Pazner        sd = div(s, dim)
14*6cf3b68dSWill Pazner        if r > 0
15*6cf3b68dSWill Pazner            sd += 1
16*6cf3b68dSWill Pazner            r -= 1
17*6cf3b68dSWill Pazner        end
18*6cf3b68dSWill Pazner        dims[d] = 2^sd
19*6cf3b68dSWill Pazner    end
20*6cf3b68dSWill Pazner    dims
21*6cf3b68dSWill Paznerend
22*6cf3b68dSWill Pazner
23*6cf3b68dSWill Paznerstruct FormRestrictionMode{T} end
24*6cf3b68dSWill Paznerconst RestrictionOnly = FormRestrictionMode{:restr}()
25*6cf3b68dSWill Paznerconst StridedOnly = FormRestrictionMode{:restr_i}()
26*6cf3b68dSWill Paznerconst RestrictionAndStrided = FormRestrictionMode{:both}()
27*6cf3b68dSWill Pazner
28*6cf3b68dSWill Paznerfunction build_cartesian_restriction(
29*6cf3b68dSWill Pazner    c::Ceed,
30*6cf3b68dSWill Pazner    dim,
31*6cf3b68dSWill Pazner    nxyz,
32*6cf3b68dSWill Pazner    order,
33*6cf3b68dSWill Pazner    ncomp,
34*6cf3b68dSWill Pazner    num_qpts;
35*6cf3b68dSWill Pazner    mode::Mode=RestrictionOnly,
36*6cf3b68dSWill Pazner) where {Mode}
37*6cf3b68dSWill Pazner    p::CeedInt = order
38*6cf3b68dSWill Pazner    pp1::CeedInt = p + 1
39*6cf3b68dSWill Pazner    nnodes::CeedInt = pp1^dim # number of scal. nodes per element
40*6cf3b68dSWill Pazner    elem_qpts::CeedInt = num_qpts^dim # number of qpts per element
41*6cf3b68dSWill Pazner
42*6cf3b68dSWill Pazner    nd = CeedInt.(p*nxyz .+ 1)
43*6cf3b68dSWill Pazner    num_elem::CeedInt = prod(nxyz)
44*6cf3b68dSWill Pazner    scalar_size::CeedInt = prod(nd)
45*6cf3b68dSWill Pazner    size::CeedInt = scalar_size*ncomp
46*6cf3b68dSWill Pazner
47*6cf3b68dSWill Pazner    form_restr = (Mode() != StridedOnly)
48*6cf3b68dSWill Pazner    form_strided = (Mode() != RestrictionOnly)
49*6cf3b68dSWill Pazner
50*6cf3b68dSWill Pazner    # elem:         0             1                 n-1
51*6cf3b68dSWill Pazner    #        |---*-...-*---|---*-...-*---|- ... -|--...--|
52*6cf3b68dSWill Pazner    # nnodes:   0   1    p-1  p  p+1       2*p             n*p
53*6cf3b68dSWill Pazner
54*6cf3b68dSWill Pazner    if form_restr
55*6cf3b68dSWill Pazner        el_nodes = zeros(CeedInt, num_elem*nnodes)
56*6cf3b68dSWill Pazner        exyz = zeros(CeedInt, dim)
57*6cf3b68dSWill Pazner        @inbounds @simd for e = 0:(num_elem-1)
58*6cf3b68dSWill Pazner            re::CeedInt = e
59*6cf3b68dSWill Pazner            for d::CeedInt = 1:dim
60*6cf3b68dSWill Pazner                exyz[d] = re%nxyz[d]
61*6cf3b68dSWill Pazner                re ÷= nxyz[d]
62*6cf3b68dSWill Pazner            end
63*6cf3b68dSWill Pazner            for lnodes::CeedInt = 0:(nnodes-1)
64*6cf3b68dSWill Pazner                gnodes::CeedInt = 0
65*6cf3b68dSWill Pazner                gnodes_stride::CeedInt = 1
66*6cf3b68dSWill Pazner                rnodes::CeedInt = lnodes
67*6cf3b68dSWill Pazner                for d::CeedInt = 1:dim
68*6cf3b68dSWill Pazner                    q = rnodes÷pp1
69*6cf3b68dSWill Pazner                    r = rnodes - pp1*q
70*6cf3b68dSWill Pazner                    gnodes::CeedInt += (exyz[d]*p + r)*gnodes_stride
71*6cf3b68dSWill Pazner                    gnodes_stride::CeedInt *= nd[d]
72*6cf3b68dSWill Pazner                    rnodes = q
73*6cf3b68dSWill Pazner                end
74*6cf3b68dSWill Pazner                el_nodes[e*nnodes+lnodes+1] = gnodes
75*6cf3b68dSWill Pazner            end
76*6cf3b68dSWill Pazner        end
77*6cf3b68dSWill Pazner    end
78*6cf3b68dSWill Pazner
79*6cf3b68dSWill Pazner    restr =
80*6cf3b68dSWill Pazner        form_restr ?
81*6cf3b68dSWill Pazner        create_elem_restriction(
82*6cf3b68dSWill Pazner            c,
83*6cf3b68dSWill Pazner            num_elem,
84*6cf3b68dSWill Pazner            nnodes,
85*6cf3b68dSWill Pazner            ncomp,
86*6cf3b68dSWill Pazner            scalar_size,
87*6cf3b68dSWill Pazner            ncomp*scalar_size,
88*6cf3b68dSWill Pazner            el_nodes,
89*6cf3b68dSWill Pazner        ) :
90*6cf3b68dSWill Pazner        nothing
91*6cf3b68dSWill Pazner    restr_i =
92*6cf3b68dSWill Pazner        form_strided ?
93*6cf3b68dSWill Pazner        create_elem_restriction_strided(
94*6cf3b68dSWill Pazner            c,
95*6cf3b68dSWill Pazner            num_elem,
96*6cf3b68dSWill Pazner            elem_qpts,
97*6cf3b68dSWill Pazner            ncomp,
98*6cf3b68dSWill Pazner            ncomp*elem_qpts*num_elem,
99*6cf3b68dSWill Pazner            STRIDES_BACKEND,
100*6cf3b68dSWill Pazner        ) :
101*6cf3b68dSWill Pazner        nothing
102*6cf3b68dSWill Pazner
103*6cf3b68dSWill Pazner    return size, restr, restr_i
104*6cf3b68dSWill Paznerend
105*6cf3b68dSWill Pazner
106*6cf3b68dSWill Paznerfunction set_cartesian_mesh_coords!(dim, nxyz, mesh_order, mesh_coords)
107*6cf3b68dSWill Pazner    p = mesh_order
108*6cf3b68dSWill Pazner    nd = p*nxyz .+ 1
109*6cf3b68dSWill Pazner    num_elem::CeedInt = prod(nxyz)
110*6cf3b68dSWill Pazner    scalar_size::CeedInt = prod(nd)
111*6cf3b68dSWill Pazner
112*6cf3b68dSWill Pazner    # The H1 basis uses Lobatto quadrature points as nodes.
113*6cf3b68dSWill Pazner    nodes::Vector{CeedScalar} = lobatto_quadrature(p + 1) # nodes are in [-1,1]
114*6cf3b68dSWill Pazner    nodes = 0.5 .+ 0.5*nodes
115*6cf3b68dSWill Pazner
116*6cf3b68dSWill Pazner    @witharray coords = mesh_coords begin
117*6cf3b68dSWill Pazner        @inbounds @simd for gsnodes = 0:scalar_size-1
118*6cf3b68dSWill Pazner            rnodes = gsnodes
119*6cf3b68dSWill Pazner            for d = 1:dim
120*6cf3b68dSWill Pazner                ndd = nd[d]
121*6cf3b68dSWill Pazner                q = rnodes÷ndd
122*6cf3b68dSWill Pazner                r = rnodes - ndd*q
123*6cf3b68dSWill Pazner
124*6cf3b68dSWill Pazner                d1d = r
125*6cf3b68dSWill Pazner                coords[gsnodes+scalar_size*(d-1)+1] = ((d1d÷p) + nodes[d1d%p+1])/nxyz[d]
126*6cf3b68dSWill Pazner                rnodes = q
127*6cf3b68dSWill Pazner            end
128*6cf3b68dSWill Pazner        end
129*6cf3b68dSWill Pazner    end
130*6cf3b68dSWill Paznerend
131