16cf3b68dSWill Paznerusing LibCEED, Printf, StaticArrays 26cf3b68dSWill Pazner 36cf3b68dSWill Paznerinclude("common.jl") 46cf3b68dSWill Pazner 56cf3b68dSWill Paznerfunction transform_mesh_coords!(dim, mesh_size, mesh_coords) 66cf3b68dSWill Pazner @witharray coords = mesh_coords begin 76cf3b68dSWill Pazner @inbounds @simd for i = 1:mesh_size 86cf3b68dSWill Pazner # map [0,1] to [0,1] varying the mesh density 96cf3b68dSWill Pazner coords[i] = 0.5 + 1.0/sqrt(3.0)*sin((2.0/3.0)*pi*(coords[i] - 0.5)) 106cf3b68dSWill Pazner end 116cf3b68dSWill Pazner end 126cf3b68dSWill Pazner exact_sa = (dim == 1 ? 2 : dim == 2 ? 4 : 6) 136cf3b68dSWill Paznerend 146cf3b68dSWill Pazner 156cf3b68dSWill Paznerfunction run_ex2(; ceed_spec, dim, mesh_order, sol_order, num_qpts, prob_size, gallery) 166cf3b68dSWill Pazner ncompx = dim 176cf3b68dSWill Pazner prob_size < 0 && (prob_size = 256*1024) 186cf3b68dSWill Pazner 196cf3b68dSWill Pazner mesh_order = max(mesh_order, sol_order) 206cf3b68dSWill Pazner sol_order = mesh_order 216cf3b68dSWill Pazner 226cf3b68dSWill Pazner ceed = Ceed(ceed_spec) 236cf3b68dSWill Pazner mesh_basis = 246cf3b68dSWill Pazner create_tensor_h1_lagrange_basis(ceed, dim, ncompx, mesh_order + 1, num_qpts, GAUSS) 256cf3b68dSWill Pazner sol_basis = 266cf3b68dSWill Pazner create_tensor_h1_lagrange_basis(ceed, dim, 1, sol_order + 1, num_qpts, GAUSS) 276cf3b68dSWill Pazner 286cf3b68dSWill Pazner nxyz = get_cartesian_mesh_size(dim, sol_order, prob_size) 296cf3b68dSWill Pazner println("Mesh size: ", nxyz) 306cf3b68dSWill Pazner 316cf3b68dSWill Pazner # Build CeedElemRestriction objects describing the mesh and solution discrete 326cf3b68dSWill Pazner # representations. 33*edb2538eSJeremy L Thompson mesh_size, mesh_rstr, _ = build_cartesian_restriction( 346cf3b68dSWill Pazner ceed, 356cf3b68dSWill Pazner dim, 366cf3b68dSWill Pazner nxyz, 376cf3b68dSWill Pazner mesh_order, 386cf3b68dSWill Pazner ncompx, 396cf3b68dSWill Pazner num_qpts, 406cf3b68dSWill Pazner mode=RestrictionOnly, 416cf3b68dSWill Pazner ) 42*edb2538eSJeremy L Thompson sol_size, _, qdata_rstr_i = build_cartesian_restriction( 436cf3b68dSWill Pazner ceed, 446cf3b68dSWill Pazner dim, 456cf3b68dSWill Pazner nxyz, 466cf3b68dSWill Pazner sol_order, 476cf3b68dSWill Pazner div(dim*(dim + 1), 2), 486cf3b68dSWill Pazner num_qpts, 496cf3b68dSWill Pazner mode=StridedOnly, 506cf3b68dSWill Pazner ) 51*edb2538eSJeremy L Thompson sol_size, sol_rstr, sol_rstr_i = build_cartesian_restriction( 526cf3b68dSWill Pazner ceed, 536cf3b68dSWill Pazner dim, 546cf3b68dSWill Pazner nxyz, 556cf3b68dSWill Pazner sol_order, 566cf3b68dSWill Pazner 1, 576cf3b68dSWill Pazner num_qpts, 586cf3b68dSWill Pazner mode=RestrictionAndStrided, 596cf3b68dSWill Pazner ) 606cf3b68dSWill Pazner println("Number of mesh nodes : ", div(mesh_size, dim)) 616cf3b68dSWill Pazner println("Number of solution nodes : ", sol_size) 626cf3b68dSWill Pazner 636cf3b68dSWill Pazner # Create a CeedVector with the mesh coordinates. 646cf3b68dSWill Pazner mesh_coords = CeedVector(ceed, mesh_size) 656cf3b68dSWill Pazner set_cartesian_mesh_coords!(dim, nxyz, mesh_order, mesh_coords) 666cf3b68dSWill Pazner 676cf3b68dSWill Pazner # Apply a transformation to the mesh. 686cf3b68dSWill Pazner exact_sa = transform_mesh_coords!(dim, mesh_size, mesh_coords) 696cf3b68dSWill Pazner 706cf3b68dSWill Pazner # Create the Q-function that builds the diffusion operator (i.e. computes its 716cf3b68dSWill Pazner # quadrature data) and set its context data. 726cf3b68dSWill Pazner if !gallery 736cf3b68dSWill Pazner @interior_qf build_qfunc = ( 746cf3b68dSWill Pazner ceed, 756cf3b68dSWill Pazner dim=dim, 766cf3b68dSWill Pazner (J, :in, EVAL_GRAD, dim, dim), 776cf3b68dSWill Pazner (w, :in, EVAL_WEIGHT), 786cf3b68dSWill Pazner (qdata, :out, EVAL_NONE, dim*(dim + 1)÷2), 796cf3b68dSWill Pazner begin 806cf3b68dSWill Pazner Jinv = inv(J) 816cf3b68dSWill Pazner qdata .= setvoigt(w*det(J)*Jinv*Jinv') 826cf3b68dSWill Pazner end, 836cf3b68dSWill Pazner ) 846cf3b68dSWill Pazner else 856cf3b68dSWill Pazner build_qfunc = create_interior_qfunction(ceed, "Poisson$(dim)DBuild") 866cf3b68dSWill Pazner end 876cf3b68dSWill Pazner 886cf3b68dSWill Pazner # Create the operator that builds the quadrature data for the diffusion 896cf3b68dSWill Pazner # operator. 906cf3b68dSWill Pazner build_oper = Operator( 916cf3b68dSWill Pazner ceed, 926cf3b68dSWill Pazner qf=build_qfunc, 936cf3b68dSWill Pazner fields=[ 94*edb2538eSJeremy L Thompson (gallery ? :dx : :J, mesh_rstr, mesh_basis, CeedVectorActive()), 956cf3b68dSWill Pazner (gallery ? :weights : :w, ElemRestrictionNone(), mesh_basis, CeedVectorNone()), 96*edb2538eSJeremy L Thompson (:qdata, qdata_rstr_i, BasisNone(), CeedVectorActive()), 976cf3b68dSWill Pazner ], 986cf3b68dSWill Pazner ) 996cf3b68dSWill Pazner 1006cf3b68dSWill Pazner # Compute the quadrature data for the diffusion operator. 1016cf3b68dSWill Pazner elem_qpts = num_qpts^dim 1026cf3b68dSWill Pazner num_elem = prod(nxyz) 1036cf3b68dSWill Pazner qdata = CeedVector(ceed, num_elem*elem_qpts*div(dim*(dim + 1), 2)) 1046cf3b68dSWill Pazner print("Computing the quadrature data for the diffusion operator ...") 1056cf3b68dSWill Pazner flush(stdout) 1066cf3b68dSWill Pazner apply!(build_oper, mesh_coords, qdata) 1076cf3b68dSWill Pazner println(" done.") 1086cf3b68dSWill Pazner 1096cf3b68dSWill Pazner # Create the Q-function that defines the action of the diffusion operator. 1106cf3b68dSWill Pazner if !gallery 1116cf3b68dSWill Pazner @interior_qf apply_qfunc = ( 1126cf3b68dSWill Pazner ceed, 1136cf3b68dSWill Pazner dim=dim, 1146cf3b68dSWill Pazner (du, :in, EVAL_GRAD, dim), 1156cf3b68dSWill Pazner (qdata, :in, EVAL_NONE, dim*(dim + 1)÷2), 1166cf3b68dSWill Pazner (dv, :out, EVAL_GRAD, dim), 1176cf3b68dSWill Pazner begin 1186cf3b68dSWill Pazner dXdxdXdxT = getvoigt(qdata) 1196cf3b68dSWill Pazner dv .= dXdxdXdxT*du 1206cf3b68dSWill Pazner end, 1216cf3b68dSWill Pazner ) 1226cf3b68dSWill Pazner else 1236cf3b68dSWill Pazner apply_qfunc = create_interior_qfunction(ceed, "Poisson$(dim)DApply") 1246cf3b68dSWill Pazner end 1256cf3b68dSWill Pazner 1266cf3b68dSWill Pazner # Create the diffusion operator. 1276cf3b68dSWill Pazner oper = Operator( 1286cf3b68dSWill Pazner ceed, 1296cf3b68dSWill Pazner qf=apply_qfunc, 1306cf3b68dSWill Pazner fields=[ 131*edb2538eSJeremy L Thompson (:du, sol_rstr, sol_basis, CeedVectorActive()), 132*edb2538eSJeremy L Thompson (:qdata, qdata_rstr_i, BasisNone(), qdata), 133*edb2538eSJeremy L Thompson (:dv, sol_rstr, sol_basis, CeedVectorActive()), 1346cf3b68dSWill Pazner ], 1356cf3b68dSWill Pazner ) 1366cf3b68dSWill Pazner 1376cf3b68dSWill Pazner # Compute the mesh surface area using the diff operator: 1386cf3b68dSWill Pazner # sa = 1^T \cdot abs( K \cdot x). 1396cf3b68dSWill Pazner print("Computing the mesh surface area using the formula: sa = 1^T.|K.x| ...") 1406cf3b68dSWill Pazner flush(stdout) 1416cf3b68dSWill Pazner 1426cf3b68dSWill Pazner # Create auxiliary solution-size vectors. 1436cf3b68dSWill Pazner u = CeedVector(ceed, sol_size) 1446cf3b68dSWill Pazner v = CeedVector(ceed, sol_size) 1456cf3b68dSWill Pazner # Initialize 'u' with sum of coordinates, x+y+z. 1469c774eddSJeremy L Thompson u[] = 0.0 1476cf3b68dSWill Pazner @witharray_read( 1486cf3b68dSWill Pazner x_host = mesh_coords, 1496cf3b68dSWill Pazner size = (mesh_size÷dim, dim), 1506cf3b68dSWill Pazner @witharray(u_host = u, size = (sol_size, 1), sum!(u_host, x_host)) 1516cf3b68dSWill Pazner ) 1526cf3b68dSWill Pazner 1536cf3b68dSWill Pazner # Apply the diffusion operator: 'u' -> 'v'. 1546cf3b68dSWill Pazner apply!(oper, u, v) 1556cf3b68dSWill Pazner sa = witharray_read(x -> sum(abs, x), v, MEM_HOST) 1566cf3b68dSWill Pazner 1576cf3b68dSWill Pazner println(" done.") 1586cf3b68dSWill Pazner @printf("Exact mesh surface area : % .14g\n", exact_sa) 1596cf3b68dSWill Pazner @printf("Computed mesh surface area : % .14g\n", sa) 1606cf3b68dSWill Pazner @printf("Surface area error : % .14g\n", sa - exact_sa) 1616cf3b68dSWill Paznerend 1626cf3b68dSWill Pazner 1636cf3b68dSWill Paznerrun_ex2( 1646cf3b68dSWill Pazner ceed_spec="/cpu/self", 1656cf3b68dSWill Pazner dim=3, 1666cf3b68dSWill Pazner mesh_order=4, 1676cf3b68dSWill Pazner sol_order=4, 1686cf3b68dSWill Pazner num_qpts=6, 1696cf3b68dSWill Pazner prob_size=-1, 1706cf3b68dSWill Pazner gallery=false, 1716cf3b68dSWill Pazner) 172