1636cccdbSjeremylt #include <stdio.h> 2e83e87a5Sjeremylt #include "../include/libceedsetup.h" 3e83e87a5Sjeremylt #include "../include/petscutils.h" 4e83e87a5Sjeremylt 5e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 6e83e87a5Sjeremylt // Destroy libCEED operator objects 7e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 8e83e87a5Sjeremylt PetscErrorCode CeedDataDestroy(CeedInt i, CeedData data) { 9e83e87a5Sjeremylt int ierr; 10e83e87a5Sjeremylt 115dfaedb8SJed Brown PetscFunctionBeginUser; 129b072555Sjeremylt CeedVectorDestroy(&data->q_data); 139b072555Sjeremylt CeedVectorDestroy(&data->x_ceed); 149b072555Sjeremylt CeedVectorDestroy(&data->y_ceed); 159b072555Sjeremylt CeedBasisDestroy(&data->basis_x); 169b072555Sjeremylt CeedBasisDestroy(&data->basis_u); 179b072555Sjeremylt CeedElemRestrictionDestroy(&data->elem_restr_u); 189b072555Sjeremylt CeedElemRestrictionDestroy(&data->elem_restr_x); 199b072555Sjeremylt CeedElemRestrictionDestroy(&data->elem_restr_u_i); 209b072555Sjeremylt CeedElemRestrictionDestroy(&data->elem_restr_qd_i); 219b072555Sjeremylt CeedQFunctionDestroy(&data->qf_apply); 229b072555Sjeremylt CeedOperatorDestroy(&data->op_apply); 23e83e87a5Sjeremylt if (i > 0) { 249b072555Sjeremylt CeedOperatorDestroy(&data->op_prolong); 259b072555Sjeremylt CeedOperatorDestroy(&data->op_restrict); 26e83e87a5Sjeremylt } 27e83e87a5Sjeremylt ierr = PetscFree(data); CHKERRQ(ierr); 28e83e87a5Sjeremylt 29e83e87a5Sjeremylt PetscFunctionReturn(0); 30e83e87a5Sjeremylt }; 31e83e87a5Sjeremylt 32e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 33e83e87a5Sjeremylt // Set up libCEED for a given degree 34e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 35e83e87a5Sjeremylt PetscErrorCode SetupLibceedByDegree(DM dm, Ceed ceed, CeedInt degree, 369b072555Sjeremylt CeedInt topo_dim, CeedInt q_extra, 379b072555Sjeremylt PetscInt num_comp_x, PetscInt num_comp_u, 389b072555Sjeremylt PetscInt g_size, PetscInt xl_size, 399b072555Sjeremylt BPData bp_data, CeedData data, 409b072555Sjeremylt PetscBool setup_rhs, CeedVector rhs_ceed, 41e83e87a5Sjeremylt CeedVector *target) { 42e83e87a5Sjeremylt int ierr; 439b072555Sjeremylt DM dm_coord; 44e83e87a5Sjeremylt Vec coords; 459b072555Sjeremylt const PetscScalar *coord_array; 469b072555Sjeremylt CeedBasis basis_x, basis_u; 479b072555Sjeremylt CeedElemRestriction elem_restr_x, elem_restr_u, elem_restr_u_i, elem_restr_qd_i; 489b072555Sjeremylt CeedQFunction qf_setup_geo, qf_apply; 499b072555Sjeremylt CeedOperator op_setup_geo, op_apply; 509b072555Sjeremylt CeedVector x_coord, q_data, x_ceed, y_ceed; 51129d8736Srezgarshakeri CeedInt num_qpts, c_start, c_end, num_elem, 529b072555Sjeremylt q_data_size = bp_data.q_data_size; 53e83e87a5Sjeremylt CeedScalar R = 1, // radius of the sphere 54e83e87a5Sjeremylt l = 1.0/PetscSqrtReal(3.0); // half edge of the inscribed cube 55e83e87a5Sjeremylt 56129d8736Srezgarshakeri <<<<<<< HEAD 57de1229c5Srezgarshakeri <<<<<<< HEAD 585dfaedb8SJed Brown PetscFunctionBeginUser; 59e83e87a5Sjeremylt // CEED bases 60e83e87a5Sjeremylt P = degree + 1; 619b072555Sjeremylt Q = P + q_extra; 629b072555Sjeremylt CeedBasisCreateTensorH1Lagrange(ceed, topo_dim, num_comp_u, P, Q, 639b072555Sjeremylt bp_data.q_mode, 649b072555Sjeremylt &basis_u); 659b072555Sjeremylt CeedBasisCreateTensorH1Lagrange(ceed, topo_dim, num_comp_x, 2, Q, 669b072555Sjeremylt bp_data.q_mode, 679b072555Sjeremylt &basis_x); 689b072555Sjeremylt CeedBasisGetNumQuadraturePoints(basis_u, &num_qpts); 69e83e87a5Sjeremylt 70e83e87a5Sjeremylt // CEED restrictions 71129d8736Srezgarshakeri ======= 72129d8736Srezgarshakeri >>>>>>> 158419b6 (example/petsc: added CreateBasisFromPlex and tested with tensor basis) 737ed3e4cdSJeremy L Thompson ierr = DMSetCoordinateDim(dm, topo_dim); CHKERRQ(ierr); 74de1229c5Srezgarshakeri ======= 75de1229c5Srezgarshakeri //ierr = DMSetCoordinateDim(dm, topo_dim); CHKERRQ(ierr); 76de1229c5Srezgarshakeri >>>>>>> 0fa86f50 (example/petsc: Added CreateDistributedDM in petscutils.c and some cleanup) 779b072555Sjeremylt ierr = DMGetCoordinateDM(dm, &dm_coord); CHKERRQ(ierr); 78129d8736Srezgarshakeri 79129d8736Srezgarshakeri // CEED bases 80129d8736Srezgarshakeri ierr = CreateBasisFromPlex(ceed, dm_coord, 0, 0, 0, 0, &basis_x); CHKERRQ(ierr); 81129d8736Srezgarshakeri ierr = CreateBasisFromPlex(ceed, dm, 0, 0, 0, 0, &basis_u); CHKERRQ(ierr); 82129d8736Srezgarshakeri 83129d8736Srezgarshakeri // CEED restrictions 849b072555Sjeremylt ierr = DMPlexSetClosurePermutationTensor(dm_coord, PETSC_DETERMINE, NULL); 85e83e87a5Sjeremylt CHKERRQ(ierr); 867ed3e4cdSJeremy L Thompson ierr = CreateRestrictionFromPlex(ceed, dm_coord, 0, 0, 0, &elem_restr_x); 87e83e87a5Sjeremylt CHKERRQ(ierr); 887ed3e4cdSJeremy L Thompson ierr = CreateRestrictionFromPlex(ceed, dm, 0, 0, 0, &elem_restr_u); 89e83e87a5Sjeremylt CHKERRQ(ierr); 90e83e87a5Sjeremylt 919b072555Sjeremylt ierr = DMPlexGetHeightStratum(dm, 0, &c_start, &c_end); CHKERRQ(ierr); 929b072555Sjeremylt num_elem = c_end - c_start; 93129d8736Srezgarshakeri CeedBasisGetNumQuadraturePoints(basis_u, &num_qpts); 94e83e87a5Sjeremylt 959b072555Sjeremylt CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, num_comp_u, 969b072555Sjeremylt num_comp_u*num_elem*num_qpts, 979b072555Sjeremylt CEED_STRIDES_BACKEND, &elem_restr_u_i); 989b072555Sjeremylt CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, q_data_size, 999b072555Sjeremylt q_data_size*num_elem*num_qpts, 1009b072555Sjeremylt CEED_STRIDES_BACKEND, &elem_restr_qd_i); 101e83e87a5Sjeremylt 102e83e87a5Sjeremylt // Element coordinates 103e83e87a5Sjeremylt ierr = DMGetCoordinatesLocal(dm, &coords); CHKERRQ(ierr); 1049b072555Sjeremylt ierr = VecGetArrayRead(coords, &coord_array); CHKERRQ(ierr); 105e83e87a5Sjeremylt 1069b072555Sjeremylt CeedElemRestrictionCreateVector(elem_restr_x, &x_coord, NULL); 1079b072555Sjeremylt CeedVectorSetArray(x_coord, CEED_MEM_HOST, CEED_COPY_VALUES, 1089b072555Sjeremylt (PetscScalar *)coord_array); 1099b072555Sjeremylt ierr = VecRestoreArrayRead(coords, &coord_array); 110e83e87a5Sjeremylt 111e83e87a5Sjeremylt // Create the persistent vectors that will be needed in setup and apply 1129b072555Sjeremylt CeedVectorCreate(ceed, q_data_size*num_elem*num_qpts, &q_data); 1139b072555Sjeremylt CeedVectorCreate(ceed, xl_size, &x_ceed); 1149b072555Sjeremylt CeedVectorCreate(ceed, xl_size, &y_ceed); 115e83e87a5Sjeremylt 116e83e87a5Sjeremylt // Create the QFunction that builds the context data 1179b072555Sjeremylt CeedQFunctionCreateInterior(ceed, 1, bp_data.setup_geo, bp_data.setup_geo_loc, 1189b072555Sjeremylt &qf_setup_geo); 1199b072555Sjeremylt CeedQFunctionAddInput(qf_setup_geo, "x", num_comp_x, CEED_EVAL_INTERP); 1209b072555Sjeremylt CeedQFunctionAddInput(qf_setup_geo, "dx", num_comp_x*topo_dim, CEED_EVAL_GRAD); 1219b072555Sjeremylt CeedQFunctionAddInput(qf_setup_geo, "weight", 1, CEED_EVAL_WEIGHT); 122a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_setup_geo, "qdata", q_data_size, CEED_EVAL_NONE); 123e83e87a5Sjeremylt 124e83e87a5Sjeremylt // Create the operator that builds the quadrature data 1259b072555Sjeremylt CeedOperatorCreate(ceed, qf_setup_geo, NULL, NULL, &op_setup_geo); 1269b072555Sjeremylt CeedOperatorSetField(op_setup_geo, "x", elem_restr_x, basis_x, 1279b072555Sjeremylt CEED_VECTOR_ACTIVE); 1289b072555Sjeremylt CeedOperatorSetField(op_setup_geo, "dx", elem_restr_x, basis_x, 1299b072555Sjeremylt CEED_VECTOR_ACTIVE); 1309b072555Sjeremylt CeedOperatorSetField(op_setup_geo, "weight", CEED_ELEMRESTRICTION_NONE, basis_x, 131e83e87a5Sjeremylt CEED_VECTOR_NONE); 132a61c78d6SJeremy L Thompson CeedOperatorSetField(op_setup_geo, "qdata", elem_restr_qd_i, 133e83e87a5Sjeremylt CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 134e83e87a5Sjeremylt 1359b072555Sjeremylt // Setup q_data 1369b072555Sjeremylt CeedOperatorApply(op_setup_geo, x_coord, q_data, CEED_REQUEST_IMMEDIATE); 137e83e87a5Sjeremylt 138e83e87a5Sjeremylt // Set up PDE operator 1399b072555Sjeremylt CeedInt in_scale = bp_data.in_mode == CEED_EVAL_GRAD ? topo_dim : 1; 1409b072555Sjeremylt CeedInt out_scale = bp_data.out_mode == CEED_EVAL_GRAD ? topo_dim : 1; 1419b072555Sjeremylt CeedQFunctionCreateInterior(ceed, 1, bp_data.apply, bp_data.apply_loc, 1429b072555Sjeremylt &qf_apply); 1439b072555Sjeremylt CeedQFunctionAddInput(qf_apply, "u", num_comp_u*in_scale, bp_data.in_mode); 144a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_apply, "qdata", q_data_size, CEED_EVAL_NONE); 1459b072555Sjeremylt CeedQFunctionAddOutput(qf_apply, "v", num_comp_u*out_scale, bp_data.out_mode); 146e83e87a5Sjeremylt 147e83e87a5Sjeremylt // Create the mass or diff operator 1489b072555Sjeremylt CeedOperatorCreate(ceed, qf_apply, NULL, NULL, &op_apply); 1499b072555Sjeremylt CeedOperatorSetField(op_apply, "u", elem_restr_u, basis_u, CEED_VECTOR_ACTIVE); 150a61c78d6SJeremy L Thompson CeedOperatorSetField(op_apply, "qdata", elem_restr_qd_i, CEED_BASIS_COLLOCATED, 1519b072555Sjeremylt q_data); 1529b072555Sjeremylt CeedOperatorSetField(op_apply, "v", elem_restr_u, basis_u, CEED_VECTOR_ACTIVE); 153e83e87a5Sjeremylt 154e83e87a5Sjeremylt // Set up RHS if needed 155e83e87a5Sjeremylt if (setup_rhs) { 1569b072555Sjeremylt CeedQFunction qf_setup_rhs; 1579b072555Sjeremylt CeedOperator op_setup_rhs; 1589b072555Sjeremylt CeedVectorCreate(ceed, num_elem*num_qpts*num_comp_u, target); 159e83e87a5Sjeremylt 160e83e87a5Sjeremylt // Create the q-function that sets up the RHS and true solution 1619b072555Sjeremylt CeedQFunctionCreateInterior(ceed, 1, bp_data.setup_rhs, bp_data.setup_rhs_loc, 1629b072555Sjeremylt &qf_setup_rhs); 1639b072555Sjeremylt CeedQFunctionAddInput(qf_setup_rhs, "x", num_comp_x, CEED_EVAL_INTERP); 164a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_setup_rhs, "qdata", q_data_size, CEED_EVAL_NONE); 165a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_setup_rhs, "true solution", num_comp_u, 166a61c78d6SJeremy L Thompson CEED_EVAL_NONE); 1679b072555Sjeremylt CeedQFunctionAddOutput(qf_setup_rhs, "rhs", num_comp_u, CEED_EVAL_INTERP); 168e83e87a5Sjeremylt 169e83e87a5Sjeremylt // Create the operator that builds the RHS and true solution 1709b072555Sjeremylt CeedOperatorCreate(ceed, qf_setup_rhs, NULL, NULL, &op_setup_rhs); 1719b072555Sjeremylt CeedOperatorSetField(op_setup_rhs, "x", elem_restr_x, basis_x, 1729b072555Sjeremylt CEED_VECTOR_ACTIVE); 173a61c78d6SJeremy L Thompson CeedOperatorSetField(op_setup_rhs, "qdata", elem_restr_qd_i, 174a61c78d6SJeremy L Thompson CEED_BASIS_COLLOCATED, q_data); 175a61c78d6SJeremy L Thompson CeedOperatorSetField(op_setup_rhs, "true solution", elem_restr_u_i, 176e83e87a5Sjeremylt CEED_BASIS_COLLOCATED, *target); 1779b072555Sjeremylt CeedOperatorSetField(op_setup_rhs, "rhs", elem_restr_u, basis_u, 178e83e87a5Sjeremylt CEED_VECTOR_ACTIVE); 179e83e87a5Sjeremylt 180e83e87a5Sjeremylt // Set up the libCEED context 1819b072555Sjeremylt CeedQFunctionContext ctx_rhs_setup; 1829b072555Sjeremylt CeedQFunctionContextCreate(ceed, &ctx_rhs_setup); 1839b072555Sjeremylt CeedScalar rhs_setup_data[2] = {R, l}; 1849b072555Sjeremylt CeedQFunctionContextSetData(ctx_rhs_setup, CEED_MEM_HOST, CEED_COPY_VALUES, 1859b072555Sjeremylt sizeof rhs_setup_data, &rhs_setup_data); 1869b072555Sjeremylt CeedQFunctionSetContext(qf_setup_rhs, ctx_rhs_setup); 1879b072555Sjeremylt CeedQFunctionContextDestroy(&ctx_rhs_setup); 188e83e87a5Sjeremylt 189e83e87a5Sjeremylt // Setup RHS and target 1909b072555Sjeremylt CeedOperatorApply(op_setup_rhs, x_coord, rhs_ceed, CEED_REQUEST_IMMEDIATE); 191e83e87a5Sjeremylt 192e83e87a5Sjeremylt // Cleanup 1939b072555Sjeremylt CeedQFunctionDestroy(&qf_setup_rhs); 1949b072555Sjeremylt CeedOperatorDestroy(&op_setup_rhs); 195e83e87a5Sjeremylt } 196e83e87a5Sjeremylt 197e83e87a5Sjeremylt // Cleanup 1989b072555Sjeremylt CeedQFunctionDestroy(&qf_setup_geo); 1999b072555Sjeremylt CeedOperatorDestroy(&op_setup_geo); 2009b072555Sjeremylt CeedVectorDestroy(&x_coord); 201e83e87a5Sjeremylt 202e83e87a5Sjeremylt // Save libCEED data required for level 2039b072555Sjeremylt data->basis_x = basis_x; data->basis_u = basis_u; 2049b072555Sjeremylt data->elem_restr_x = elem_restr_x; 2059b072555Sjeremylt data->elem_restr_u = elem_restr_u; 2069b072555Sjeremylt data->elem_restr_u_i = elem_restr_u_i; 2079b072555Sjeremylt data->elem_restr_qd_i = elem_restr_qd_i; 2089b072555Sjeremylt data->qf_apply = qf_apply; 2099b072555Sjeremylt data->op_apply = op_apply; 2109b072555Sjeremylt data->q_data = q_data; 2119b072555Sjeremylt data->x_ceed = x_ceed; 2129b072555Sjeremylt data->y_ceed = y_ceed; 213e83e87a5Sjeremylt 214e83e87a5Sjeremylt PetscFunctionReturn(0); 215e83e87a5Sjeremylt }; 216e83e87a5Sjeremylt 217e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 218e83e87a5Sjeremylt // Setup libCEED level transfer operator objects 219e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 220*1c9a79dbSrezgarshakeri PetscErrorCode CeedLevelTransferSetup(DM dm, Ceed ceed, CeedInt level, 2219b072555Sjeremylt CeedInt num_comp_u, CeedData *data, 222*1c9a79dbSrezgarshakeri <<<<<<< HEAD 2239b072555Sjeremylt CeedInt *level_degrees, 2249b072555Sjeremylt CeedQFunction qf_restrict, CeedQFunction qf_prolong) { 2255dfaedb8SJed Brown PetscFunctionBeginUser; 2269b072555Sjeremylt // Return early if num_levels=1 2279b072555Sjeremylt if (num_levels == 1) 228e83e87a5Sjeremylt PetscFunctionReturn(0); 229*1c9a79dbSrezgarshakeri ======= 230*1c9a79dbSrezgarshakeri Vec fine_mult) { 231*1c9a79dbSrezgarshakeri int ierr; 232*1c9a79dbSrezgarshakeri >>>>>>> 2e9bde68 (Used "CeedOperatorMultigridLevelCreate" to create multigrid operators) 233e83e87a5Sjeremylt 234e83e87a5Sjeremylt // Restriction - Fine to corse 2359b072555Sjeremylt CeedOperator op_restrict; 236e83e87a5Sjeremylt // Interpolation - Corse to fine 2379b072555Sjeremylt CeedOperator op_prolong; 238*1c9a79dbSrezgarshakeri // Coarse grid operator 239*1c9a79dbSrezgarshakeri CeedOperator op_apply; 240*1c9a79dbSrezgarshakeri // Basis 241*1c9a79dbSrezgarshakeri CeedBasis basis_u; 242*1c9a79dbSrezgarshakeri ierr = CreateBasisFromPlex(ceed, dm, 0, 0, 0, 0, &basis_u); 243*1c9a79dbSrezgarshakeri CHKERRQ(ierr); 244e83e87a5Sjeremylt 245*1c9a79dbSrezgarshakeri // --------------------------------------------------------------------------- 246*1c9a79dbSrezgarshakeri // Coarse Grid, Prolongation, and Restriction Operators 247*1c9a79dbSrezgarshakeri // --------------------------------------------------------------------------- 248*1c9a79dbSrezgarshakeri // Create the Operators that compute the prolongation and 249*1c9a79dbSrezgarshakeri // restriction between the p-multigrid levels and the coarse grid eval. 250*1c9a79dbSrezgarshakeri // --------------------------------------------------------------------------- 251*1c9a79dbSrezgarshakeri // Place in libCEED array 252*1c9a79dbSrezgarshakeri const PetscScalar *m; 253*1c9a79dbSrezgarshakeri PetscMemType m_mem_type; 254*1c9a79dbSrezgarshakeri ierr = VecGetArrayReadAndMemType(fine_mult, &m, &m_mem_type); 255*1c9a79dbSrezgarshakeri CHKERRQ(ierr); 256*1c9a79dbSrezgarshakeri CeedVectorSetArray(data[level]->x_ceed, MemTypeP2C(m_mem_type), 257*1c9a79dbSrezgarshakeri CEED_USE_POINTER, (CeedScalar *)m); 258e83e87a5Sjeremylt 259*1c9a79dbSrezgarshakeri CeedOperatorMultigridLevelCreate(data[level]->op_apply, data[level]->x_ceed, 260*1c9a79dbSrezgarshakeri data[level-1]->elem_restr_u, basis_u, 261*1c9a79dbSrezgarshakeri &op_apply, &op_prolong, &op_restrict); 262e83e87a5Sjeremylt 263*1c9a79dbSrezgarshakeri // Restore PETSc vector 264*1c9a79dbSrezgarshakeri CeedVectorTakeArray(data[level]->x_ceed, MemTypeP2C(m_mem_type), 265*1c9a79dbSrezgarshakeri (CeedScalar **)&m); 266*1c9a79dbSrezgarshakeri ierr = VecRestoreArrayReadAndMemType(fine_mult, &m); CHKERRQ(ierr); 267*1c9a79dbSrezgarshakeri ierr = VecZeroEntries(fine_mult); CHKERRQ(ierr); 268*1c9a79dbSrezgarshakeri // -- Save libCEED data 269*1c9a79dbSrezgarshakeri data[level-1]->op_apply = op_apply; 270*1c9a79dbSrezgarshakeri data[level]->op_prolong = op_prolong; 271*1c9a79dbSrezgarshakeri data[level]->op_restrict = op_restrict; 272*1c9a79dbSrezgarshakeri 273*1c9a79dbSrezgarshakeri CeedBasisDestroy(&basis_u); 274e83e87a5Sjeremylt PetscFunctionReturn(0); 275e83e87a5Sjeremylt }; 276e83e87a5Sjeremylt 277e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 278