1*6cf3b68dSWill Paznerusing LibCEED, Printf, StaticArrays 2*6cf3b68dSWill Pazner 3*6cf3b68dSWill Paznerinclude("common.jl") 4*6cf3b68dSWill Pazner 5*6cf3b68dSWill Paznerfunction transform_mesh_coords!(dim, mesh_size, mesh_coords) 6*6cf3b68dSWill Pazner @witharray coords = mesh_coords begin 7*6cf3b68dSWill Pazner @inbounds @simd for i = 1:mesh_size 8*6cf3b68dSWill Pazner # map [0,1] to [0,1] varying the mesh density 9*6cf3b68dSWill Pazner coords[i] = 0.5 + 1.0/sqrt(3.0)*sin((2.0/3.0)*pi*(coords[i] - 0.5)) 10*6cf3b68dSWill Pazner end 11*6cf3b68dSWill Pazner end 12*6cf3b68dSWill Pazner exact_sa = (dim == 1 ? 2 : dim == 2 ? 4 : 6) 13*6cf3b68dSWill Paznerend 14*6cf3b68dSWill Pazner 15*6cf3b68dSWill Paznerfunction run_ex2(; ceed_spec, dim, mesh_order, sol_order, num_qpts, prob_size, gallery) 16*6cf3b68dSWill Pazner ncompx = dim 17*6cf3b68dSWill Pazner prob_size < 0 && (prob_size = 256*1024) 18*6cf3b68dSWill Pazner 19*6cf3b68dSWill Pazner mesh_order = max(mesh_order, sol_order) 20*6cf3b68dSWill Pazner sol_order = mesh_order 21*6cf3b68dSWill Pazner 22*6cf3b68dSWill Pazner ceed = Ceed(ceed_spec) 23*6cf3b68dSWill Pazner mesh_basis = 24*6cf3b68dSWill Pazner create_tensor_h1_lagrange_basis(ceed, dim, ncompx, mesh_order + 1, num_qpts, GAUSS) 25*6cf3b68dSWill Pazner sol_basis = 26*6cf3b68dSWill Pazner create_tensor_h1_lagrange_basis(ceed, dim, 1, sol_order + 1, num_qpts, GAUSS) 27*6cf3b68dSWill Pazner 28*6cf3b68dSWill Pazner nxyz = get_cartesian_mesh_size(dim, sol_order, prob_size) 29*6cf3b68dSWill Pazner println("Mesh size: ", nxyz) 30*6cf3b68dSWill Pazner 31*6cf3b68dSWill Pazner # Build CeedElemRestriction objects describing the mesh and solution discrete 32*6cf3b68dSWill Pazner # representations. 33*6cf3b68dSWill Pazner mesh_size, mesh_restr, _ = build_cartesian_restriction( 34*6cf3b68dSWill Pazner ceed, 35*6cf3b68dSWill Pazner dim, 36*6cf3b68dSWill Pazner nxyz, 37*6cf3b68dSWill Pazner mesh_order, 38*6cf3b68dSWill Pazner ncompx, 39*6cf3b68dSWill Pazner num_qpts, 40*6cf3b68dSWill Pazner mode=RestrictionOnly, 41*6cf3b68dSWill Pazner ) 42*6cf3b68dSWill Pazner sol_size, _, qdata_restr_i = build_cartesian_restriction( 43*6cf3b68dSWill Pazner ceed, 44*6cf3b68dSWill Pazner dim, 45*6cf3b68dSWill Pazner nxyz, 46*6cf3b68dSWill Pazner sol_order, 47*6cf3b68dSWill Pazner div(dim*(dim + 1), 2), 48*6cf3b68dSWill Pazner num_qpts, 49*6cf3b68dSWill Pazner mode=StridedOnly, 50*6cf3b68dSWill Pazner ) 51*6cf3b68dSWill Pazner sol_size, sol_restr, sol_restr_i = build_cartesian_restriction( 52*6cf3b68dSWill Pazner ceed, 53*6cf3b68dSWill Pazner dim, 54*6cf3b68dSWill Pazner nxyz, 55*6cf3b68dSWill Pazner sol_order, 56*6cf3b68dSWill Pazner 1, 57*6cf3b68dSWill Pazner num_qpts, 58*6cf3b68dSWill Pazner mode=RestrictionAndStrided, 59*6cf3b68dSWill Pazner ) 60*6cf3b68dSWill Pazner println("Number of mesh nodes : ", div(mesh_size, dim)) 61*6cf3b68dSWill Pazner println("Number of solution nodes : ", sol_size) 62*6cf3b68dSWill Pazner 63*6cf3b68dSWill Pazner # Create a CeedVector with the mesh coordinates. 64*6cf3b68dSWill Pazner mesh_coords = CeedVector(ceed, mesh_size) 65*6cf3b68dSWill Pazner set_cartesian_mesh_coords!(dim, nxyz, mesh_order, mesh_coords) 66*6cf3b68dSWill Pazner 67*6cf3b68dSWill Pazner # Apply a transformation to the mesh. 68*6cf3b68dSWill Pazner exact_sa = transform_mesh_coords!(dim, mesh_size, mesh_coords) 69*6cf3b68dSWill Pazner 70*6cf3b68dSWill Pazner # Create the Q-function that builds the diffusion operator (i.e. computes its 71*6cf3b68dSWill Pazner # quadrature data) and set its context data. 72*6cf3b68dSWill Pazner if !gallery 73*6cf3b68dSWill Pazner @interior_qf build_qfunc = ( 74*6cf3b68dSWill Pazner ceed, 75*6cf3b68dSWill Pazner dim=dim, 76*6cf3b68dSWill Pazner (J, :in, EVAL_GRAD, dim, dim), 77*6cf3b68dSWill Pazner (w, :in, EVAL_WEIGHT), 78*6cf3b68dSWill Pazner (qdata, :out, EVAL_NONE, dim*(dim + 1)÷2), 79*6cf3b68dSWill Pazner begin 80*6cf3b68dSWill Pazner Jinv = inv(J) 81*6cf3b68dSWill Pazner qdata .= setvoigt(w*det(J)*Jinv*Jinv') 82*6cf3b68dSWill Pazner end, 83*6cf3b68dSWill Pazner ) 84*6cf3b68dSWill Pazner else 85*6cf3b68dSWill Pazner build_qfunc = create_interior_qfunction(ceed, "Poisson$(dim)DBuild") 86*6cf3b68dSWill Pazner end 87*6cf3b68dSWill Pazner 88*6cf3b68dSWill Pazner # Create the operator that builds the quadrature data for the diffusion 89*6cf3b68dSWill Pazner # operator. 90*6cf3b68dSWill Pazner build_oper = Operator( 91*6cf3b68dSWill Pazner ceed, 92*6cf3b68dSWill Pazner qf=build_qfunc, 93*6cf3b68dSWill Pazner fields=[ 94*6cf3b68dSWill Pazner (gallery ? :dx : :J, mesh_restr, mesh_basis, CeedVectorActive()), 95*6cf3b68dSWill Pazner (gallery ? :weights : :w, ElemRestrictionNone(), mesh_basis, CeedVectorNone()), 96*6cf3b68dSWill Pazner (:qdata, qdata_restr_i, BasisCollocated(), CeedVectorActive()), 97*6cf3b68dSWill Pazner ], 98*6cf3b68dSWill Pazner ) 99*6cf3b68dSWill Pazner 100*6cf3b68dSWill Pazner # Compute the quadrature data for the diffusion operator. 101*6cf3b68dSWill Pazner elem_qpts = num_qpts^dim 102*6cf3b68dSWill Pazner num_elem = prod(nxyz) 103*6cf3b68dSWill Pazner qdata = CeedVector(ceed, num_elem*elem_qpts*div(dim*(dim + 1), 2)) 104*6cf3b68dSWill Pazner print("Computing the quadrature data for the diffusion operator ...") 105*6cf3b68dSWill Pazner flush(stdout) 106*6cf3b68dSWill Pazner apply!(build_oper, mesh_coords, qdata) 107*6cf3b68dSWill Pazner println(" done.") 108*6cf3b68dSWill Pazner 109*6cf3b68dSWill Pazner # Create the Q-function that defines the action of the diffusion operator. 110*6cf3b68dSWill Pazner if !gallery 111*6cf3b68dSWill Pazner @interior_qf apply_qfunc = ( 112*6cf3b68dSWill Pazner ceed, 113*6cf3b68dSWill Pazner dim=dim, 114*6cf3b68dSWill Pazner (du, :in, EVAL_GRAD, dim), 115*6cf3b68dSWill Pazner (qdata, :in, EVAL_NONE, dim*(dim + 1)÷2), 116*6cf3b68dSWill Pazner (dv, :out, EVAL_GRAD, dim), 117*6cf3b68dSWill Pazner begin 118*6cf3b68dSWill Pazner dXdxdXdxT = getvoigt(qdata) 119*6cf3b68dSWill Pazner dv .= dXdxdXdxT*du 120*6cf3b68dSWill Pazner end, 121*6cf3b68dSWill Pazner ) 122*6cf3b68dSWill Pazner else 123*6cf3b68dSWill Pazner apply_qfunc = create_interior_qfunction(ceed, "Poisson$(dim)DApply") 124*6cf3b68dSWill Pazner end 125*6cf3b68dSWill Pazner 126*6cf3b68dSWill Pazner # Create the diffusion operator. 127*6cf3b68dSWill Pazner oper = Operator( 128*6cf3b68dSWill Pazner ceed, 129*6cf3b68dSWill Pazner qf=apply_qfunc, 130*6cf3b68dSWill Pazner fields=[ 131*6cf3b68dSWill Pazner (:du, sol_restr, sol_basis, CeedVectorActive()), 132*6cf3b68dSWill Pazner (:qdata, qdata_restr_i, BasisCollocated(), qdata), 133*6cf3b68dSWill Pazner (:dv, sol_restr, sol_basis, CeedVectorActive()), 134*6cf3b68dSWill Pazner ], 135*6cf3b68dSWill Pazner ) 136*6cf3b68dSWill Pazner 137*6cf3b68dSWill Pazner # Compute the mesh surface area using the diff operator: 138*6cf3b68dSWill Pazner # sa = 1^T \cdot abs( K \cdot x). 139*6cf3b68dSWill Pazner print("Computing the mesh surface area using the formula: sa = 1^T.|K.x| ...") 140*6cf3b68dSWill Pazner flush(stdout) 141*6cf3b68dSWill Pazner 142*6cf3b68dSWill Pazner # Create auxiliary solution-size vectors. 143*6cf3b68dSWill Pazner u = CeedVector(ceed, sol_size) 144*6cf3b68dSWill Pazner v = CeedVector(ceed, sol_size) 145*6cf3b68dSWill Pazner # Initialize 'u' with sum of coordinates, x+y+z. 146*6cf3b68dSWill Pazner @witharray_read( 147*6cf3b68dSWill Pazner x_host = mesh_coords, 148*6cf3b68dSWill Pazner size = (mesh_size÷dim, dim), 149*6cf3b68dSWill Pazner @witharray(u_host = u, size = (sol_size, 1), sum!(u_host, x_host)) 150*6cf3b68dSWill Pazner ) 151*6cf3b68dSWill Pazner 152*6cf3b68dSWill Pazner # Apply the diffusion operator: 'u' -> 'v'. 153*6cf3b68dSWill Pazner apply!(oper, u, v) 154*6cf3b68dSWill Pazner sa = witharray_read(x -> sum(abs, x), v, MEM_HOST) 155*6cf3b68dSWill Pazner 156*6cf3b68dSWill Pazner println(" done.") 157*6cf3b68dSWill Pazner @printf("Exact mesh surface area : % .14g\n", exact_sa) 158*6cf3b68dSWill Pazner @printf("Computed mesh surface area : % .14g\n", sa) 159*6cf3b68dSWill Pazner @printf("Surface area error : % .14g\n", sa - exact_sa) 160*6cf3b68dSWill Paznerend 161*6cf3b68dSWill Pazner 162*6cf3b68dSWill Paznerrun_ex2( 163*6cf3b68dSWill Pazner ceed_spec="/cpu/self", 164*6cf3b68dSWill Pazner dim=3, 165*6cf3b68dSWill Pazner mesh_order=4, 166*6cf3b68dSWill Pazner sol_order=4, 167*6cf3b68dSWill Pazner num_qpts=6, 168*6cf3b68dSWill Pazner prob_size=-1, 169*6cf3b68dSWill Pazner gallery=false, 170*6cf3b68dSWill Pazner) 171