xref: /libCEED/julia/LibCEED.jl/examples/common.jl (revision 21f16bf6c2940c092555e126518ed0c98a2b88a9)
16cf3b68dSWill Paznerfunction get_cartesian_mesh_size(dim, order, prob_size)
26cf3b68dSWill Pazner    dims = zeros(CeedInt, dim)
36cf3b68dSWill Pazner    # Use the approximate formula:
46cf3b68dSWill Pazner    #    prob_size ~ num_elem * order^dim
56cf3b68dSWill Pazner    num_elem = div(prob_size, order^dim)
66cf3b68dSWill Pazner    s = 0 # find s: num_elem/2 < 2^s <= num_elem
76cf3b68dSWill Pazner    while num_elem > 1
86cf3b68dSWill Pazner        num_elem = div(num_elem, 2)
96cf3b68dSWill Pazner        s += 1
106cf3b68dSWill Pazner    end
116cf3b68dSWill Pazner    r = s%dim
126cf3b68dSWill Pazner    for d = 1:dim
136cf3b68dSWill Pazner        sd = div(s, dim)
146cf3b68dSWill Pazner        if r > 0
156cf3b68dSWill Pazner            sd += 1
166cf3b68dSWill Pazner            r -= 1
176cf3b68dSWill Pazner        end
186cf3b68dSWill Pazner        dims[d] = 2^sd
196cf3b68dSWill Pazner    end
206cf3b68dSWill Pazner    dims
216cf3b68dSWill Paznerend
226cf3b68dSWill Pazner
236cf3b68dSWill Paznerstruct FormRestrictionMode{T} end
24*edb2538eSJeremy L Thompsonconst RestrictionOnly = FormRestrictionMode{:rstr}()
25*edb2538eSJeremy L Thompsonconst StridedOnly = FormRestrictionMode{:rstr_i}()
266cf3b68dSWill Paznerconst RestrictionAndStrided = FormRestrictionMode{:both}()
276cf3b68dSWill Pazner
286cf3b68dSWill Paznerfunction build_cartesian_restriction(
296cf3b68dSWill Pazner    c::Ceed,
306cf3b68dSWill Pazner    dim,
316cf3b68dSWill Pazner    nxyz,
326cf3b68dSWill Pazner    order,
336cf3b68dSWill Pazner    ncomp,
346cf3b68dSWill Pazner    num_qpts;
356cf3b68dSWill Pazner    mode::Mode=RestrictionOnly,
366cf3b68dSWill Pazner) where {Mode}
376cf3b68dSWill Pazner    p::CeedInt = order
386cf3b68dSWill Pazner    pp1::CeedInt = p + 1
396cf3b68dSWill Pazner    nnodes::CeedInt = pp1^dim # number of scal. nodes per element
406cf3b68dSWill Pazner    elem_qpts::CeedInt = num_qpts^dim # number of qpts per element
416cf3b68dSWill Pazner
426cf3b68dSWill Pazner    nd = CeedInt.(p*nxyz .+ 1)
436cf3b68dSWill Pazner    num_elem::CeedInt = prod(nxyz)
446cf3b68dSWill Pazner    scalar_size::CeedInt = prod(nd)
456cf3b68dSWill Pazner    size::CeedInt = scalar_size*ncomp
466cf3b68dSWill Pazner
47*edb2538eSJeremy L Thompson    form_rstr = (Mode() != StridedOnly)
486cf3b68dSWill Pazner    form_strided = (Mode() != RestrictionOnly)
496cf3b68dSWill Pazner
506cf3b68dSWill Pazner    # elem:         0             1                 n-1
516cf3b68dSWill Pazner    #        |---*-...-*---|---*-...-*---|- ... -|--...--|
526cf3b68dSWill Pazner    # nnodes:   0   1    p-1  p  p+1       2*p             n*p
536cf3b68dSWill Pazner
54*edb2538eSJeremy L Thompson    if form_rstr
556cf3b68dSWill Pazner        el_nodes = zeros(CeedInt, num_elem*nnodes)
566cf3b68dSWill Pazner        exyz = zeros(CeedInt, dim)
576cf3b68dSWill Pazner        @inbounds @simd for e = 0:(num_elem-1)
586cf3b68dSWill Pazner            re::CeedInt = e
596cf3b68dSWill Pazner            for d::CeedInt = 1:dim
606cf3b68dSWill Pazner                exyz[d] = re%nxyz[d]
616cf3b68dSWill Pazner                re ÷= nxyz[d]
626cf3b68dSWill Pazner            end
636cf3b68dSWill Pazner            for lnodes::CeedInt = 0:(nnodes-1)
646cf3b68dSWill Pazner                gnodes::CeedInt = 0
656cf3b68dSWill Pazner                gnodes_stride::CeedInt = 1
666cf3b68dSWill Pazner                rnodes::CeedInt = lnodes
676cf3b68dSWill Pazner                for d::CeedInt = 1:dim
686cf3b68dSWill Pazner                    q = rnodes÷pp1
696cf3b68dSWill Pazner                    r = rnodes - pp1*q
706cf3b68dSWill Pazner                    gnodes::CeedInt += (exyz[d]*p + r)*gnodes_stride
716cf3b68dSWill Pazner                    gnodes_stride::CeedInt *= nd[d]
726cf3b68dSWill Pazner                    rnodes = q
736cf3b68dSWill Pazner                end
746cf3b68dSWill Pazner                el_nodes[e*nnodes+lnodes+1] = gnodes
756cf3b68dSWill Pazner            end
766cf3b68dSWill Pazner        end
776cf3b68dSWill Pazner    end
786cf3b68dSWill Pazner
79*edb2538eSJeremy L Thompson    rstr =
80*edb2538eSJeremy L Thompson        form_rstr ?
816cf3b68dSWill Pazner        create_elem_restriction(
826cf3b68dSWill Pazner            c,
836cf3b68dSWill Pazner            num_elem,
846cf3b68dSWill Pazner            nnodes,
856cf3b68dSWill Pazner            ncomp,
866cf3b68dSWill Pazner            scalar_size,
876cf3b68dSWill Pazner            ncomp*scalar_size,
886cf3b68dSWill Pazner            el_nodes,
89cdf95791SWill Pazner        ) : nothing
90*edb2538eSJeremy L Thompson    rstr_i =
916cf3b68dSWill Pazner        form_strided ?
926cf3b68dSWill Pazner        create_elem_restriction_strided(
936cf3b68dSWill Pazner            c,
946cf3b68dSWill Pazner            num_elem,
956cf3b68dSWill Pazner            elem_qpts,
966cf3b68dSWill Pazner            ncomp,
976cf3b68dSWill Pazner            ncomp*elem_qpts*num_elem,
986cf3b68dSWill Pazner            STRIDES_BACKEND,
99cdf95791SWill Pazner        ) : nothing
1006cf3b68dSWill Pazner
101*edb2538eSJeremy L Thompson    return size, rstr, rstr_i
1026cf3b68dSWill Paznerend
1036cf3b68dSWill Pazner
1046cf3b68dSWill Paznerfunction set_cartesian_mesh_coords!(dim, nxyz, mesh_order, mesh_coords)
1056cf3b68dSWill Pazner    p = mesh_order
1066cf3b68dSWill Pazner    nd = p*nxyz .+ 1
1076cf3b68dSWill Pazner    num_elem::CeedInt = prod(nxyz)
1086cf3b68dSWill Pazner    scalar_size::CeedInt = prod(nd)
1096cf3b68dSWill Pazner
1106cf3b68dSWill Pazner    # The H1 basis uses Lobatto quadrature points as nodes.
1116cf3b68dSWill Pazner    nodes::Vector{CeedScalar} = lobatto_quadrature(p + 1) # nodes are in [-1,1]
1126cf3b68dSWill Pazner    nodes = 0.5 .+ 0.5*nodes
1136cf3b68dSWill Pazner
1146cf3b68dSWill Pazner    @witharray coords = mesh_coords begin
1156cf3b68dSWill Pazner        @inbounds @simd for gsnodes = 0:scalar_size-1
1166cf3b68dSWill Pazner            rnodes = gsnodes
1176cf3b68dSWill Pazner            for d = 1:dim
1186cf3b68dSWill Pazner                ndd = nd[d]
1196cf3b68dSWill Pazner                q = rnodes÷ndd
1206cf3b68dSWill Pazner                r = rnodes - ndd*q
1216cf3b68dSWill Pazner
1226cf3b68dSWill Pazner                d1d = r
1236cf3b68dSWill Pazner                coords[gsnodes+scalar_size*(d-1)+1] = ((d1d÷p) + nodes[d1d%p+1])/nxyz[d]
1246cf3b68dSWill Pazner                rnodes = q
1256cf3b68dSWill Pazner            end
1266cf3b68dSWill Pazner        end
1276cf3b68dSWill Pazner    end
1286cf3b68dSWill Paznerend
129