1e83e87a5Sjeremylt #include "../include/matops.h" 22b730f8bSJeremy L Thompson 3e83e87a5Sjeremylt #include "../include/petscutils.h" 4e83e87a5Sjeremylt 5e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 66c88e6a2Srezgarshakeri // Setup apply operator context data 76c88e6a2Srezgarshakeri // ----------------------------------------------------------------------------- 82b730f8bSJeremy L Thompson PetscErrorCode SetupApplyOperatorCtx(MPI_Comm comm, DM dm, Ceed ceed, CeedData ceed_data, Vec X_loc, OperatorApplyContext op_apply_ctx) { 96c88e6a2Srezgarshakeri PetscFunctionBeginUser; 106c88e6a2Srezgarshakeri op_apply_ctx->comm = comm; 116c88e6a2Srezgarshakeri op_apply_ctx->dm = dm; 126c88e6a2Srezgarshakeri op_apply_ctx->X_loc = X_loc; 132b730f8bSJeremy L Thompson PetscCall(VecDuplicate(X_loc, &op_apply_ctx->Y_loc)); 146c88e6a2Srezgarshakeri op_apply_ctx->x_ceed = ceed_data->x_ceed; 156c88e6a2Srezgarshakeri op_apply_ctx->y_ceed = ceed_data->y_ceed; 166c88e6a2Srezgarshakeri op_apply_ctx->op = ceed_data->op_apply; 176c88e6a2Srezgarshakeri op_apply_ctx->ceed = ceed; 18ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 196c88e6a2Srezgarshakeri } 206c88e6a2Srezgarshakeri 216c88e6a2Srezgarshakeri // ----------------------------------------------------------------------------- 226c88e6a2Srezgarshakeri // Setup error operator context data 236c88e6a2Srezgarshakeri // ----------------------------------------------------------------------------- 242b730f8bSJeremy L Thompson PetscErrorCode SetupErrorOperatorCtx(MPI_Comm comm, DM dm, Ceed ceed, CeedData ceed_data, Vec X_loc, CeedOperator op_error, 256c88e6a2Srezgarshakeri OperatorApplyContext op_error_ctx) { 266c88e6a2Srezgarshakeri PetscFunctionBeginUser; 276c88e6a2Srezgarshakeri op_error_ctx->comm = comm; 286c88e6a2Srezgarshakeri op_error_ctx->dm = dm; 296c88e6a2Srezgarshakeri op_error_ctx->X_loc = X_loc; 302b730f8bSJeremy L Thompson PetscCall(VecDuplicate(X_loc, &op_error_ctx->Y_loc)); 316c88e6a2Srezgarshakeri op_error_ctx->x_ceed = ceed_data->x_ceed; 326c88e6a2Srezgarshakeri op_error_ctx->y_ceed = ceed_data->y_ceed; 336c88e6a2Srezgarshakeri op_error_ctx->op = op_error; 346c88e6a2Srezgarshakeri op_error_ctx->ceed = ceed; 35ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 366c88e6a2Srezgarshakeri } 376c88e6a2Srezgarshakeri 386c88e6a2Srezgarshakeri // ----------------------------------------------------------------------------- 39e83e87a5Sjeremylt // This function returns the computed diagonal of the operator 40e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 41e83e87a5Sjeremylt PetscErrorCode MatGetDiag(Mat A, Vec D) { 42d4d45553Srezgarshakeri OperatorApplyContext op_apply_ctx; 43e83e87a5Sjeremylt 44e83e87a5Sjeremylt PetscFunctionBeginUser; 452b730f8bSJeremy L Thompson PetscCall(MatShellGetContext(A, &op_apply_ctx)); 46e83e87a5Sjeremylt 47e83e87a5Sjeremylt // Compute Diagonal via libCEED 489b072555Sjeremylt PetscMemType mem_type; 49e83e87a5Sjeremylt 50179e5961SZach Atkins // Place PETSc vector in libCEED vector 51179e5961SZach Atkins PetscCall(VecP2C(op_apply_ctx->Y_loc, &mem_type, op_apply_ctx->y_ceed)); 52e83e87a5Sjeremylt 53179e5961SZach Atkins // Compute Diagonal 542b730f8bSJeremy L Thompson CeedOperatorLinearAssembleDiagonal(op_apply_ctx->op, op_apply_ctx->y_ceed, CEED_REQUEST_IMMEDIATE); 55e83e87a5Sjeremylt 56179e5961SZach Atkins // Local-to-Global 57179e5961SZach Atkins PetscCall(VecC2P(op_apply_ctx->y_ceed, mem_type, op_apply_ctx->Y_loc)); 582b730f8bSJeremy L Thompson PetscCall(VecZeroEntries(D)); 592b730f8bSJeremy L Thompson PetscCall(DMLocalToGlobal(op_apply_ctx->dm, op_apply_ctx->Y_loc, ADD_VALUES, D)); 60ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 61fd8f24faSSebastian Grimberg } 62e83e87a5Sjeremylt 63e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 64ea61e9acSJeremy L Thompson // This function uses libCEED to compute the action of the Laplacian with Dirichlet boundary conditions 65e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 662b730f8bSJeremy L Thompson PetscErrorCode ApplyLocal_Ceed(Vec X, Vec Y, OperatorApplyContext op_apply_ctx) { 679b072555Sjeremylt PetscMemType x_mem_type, y_mem_type; 68e83e87a5Sjeremylt 69e83e87a5Sjeremylt PetscFunctionBeginUser; 70e83e87a5Sjeremylt // Global-to-local 712b730f8bSJeremy L Thompson PetscCall(DMGlobalToLocal(op_apply_ctx->dm, X, INSERT_VALUES, op_apply_ctx->X_loc)); 72e83e87a5Sjeremylt 73e83e87a5Sjeremylt // Setup libCEED vectors 74179e5961SZach Atkins PetscCall(VecReadP2C(op_apply_ctx->X_loc, &x_mem_type, op_apply_ctx->x_ceed)); 75179e5961SZach Atkins PetscCall(VecP2C(op_apply_ctx->Y_loc, &y_mem_type, op_apply_ctx->y_ceed)); 76e83e87a5Sjeremylt 77e83e87a5Sjeremylt // Apply libCEED operator 782b730f8bSJeremy L Thompson CeedOperatorApply(op_apply_ctx->op, op_apply_ctx->x_ceed, op_apply_ctx->y_ceed, CEED_REQUEST_IMMEDIATE); 79e83e87a5Sjeremylt 80e83e87a5Sjeremylt // Restore PETSc vectors 81179e5961SZach Atkins PetscCall(VecReadC2P(op_apply_ctx->x_ceed, x_mem_type, op_apply_ctx->X_loc)); 82179e5961SZach Atkins PetscCall(VecC2P(op_apply_ctx->y_ceed, y_mem_type, op_apply_ctx->Y_loc)); 83e83e87a5Sjeremylt 84e83e87a5Sjeremylt // Local-to-global 852b730f8bSJeremy L Thompson PetscCall(VecZeroEntries(Y)); 862b730f8bSJeremy L Thompson PetscCall(DMLocalToGlobal(op_apply_ctx->dm, op_apply_ctx->Y_loc, ADD_VALUES, Y)); 87ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 88fd8f24faSSebastian Grimberg } 89e83e87a5Sjeremylt 90e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 91e83e87a5Sjeremylt // This function wraps the libCEED operator for a MatShell 92e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 93e83e87a5Sjeremylt PetscErrorCode MatMult_Ceed(Mat A, Vec X, Vec Y) { 94d4d45553Srezgarshakeri OperatorApplyContext op_apply_ctx; 95e83e87a5Sjeremylt 96e83e87a5Sjeremylt PetscFunctionBeginUser; 972b730f8bSJeremy L Thompson PetscCall(MatShellGetContext(A, &op_apply_ctx)); 98e83e87a5Sjeremylt 99e83e87a5Sjeremylt // libCEED for local action of residual evaluator 1002b730f8bSJeremy L Thompson PetscCall(ApplyLocal_Ceed(X, Y, op_apply_ctx)); 101ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 102fd8f24faSSebastian Grimberg } 103e83e87a5Sjeremylt 104e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 105e83e87a5Sjeremylt // This function uses libCEED to compute the action of the prolongation operator 106e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 107e83e87a5Sjeremylt PetscErrorCode MatMult_Prolong(Mat A, Vec X, Vec Y) { 108d4d45553Srezgarshakeri ProlongRestrContext pr_restr_ctx; 1099b072555Sjeremylt PetscMemType c_mem_type, f_mem_type; 110e83e87a5Sjeremylt 111e83e87a5Sjeremylt PetscFunctionBeginUser; 1122b730f8bSJeremy L Thompson PetscCall(MatShellGetContext(A, &pr_restr_ctx)); 113e83e87a5Sjeremylt 114e83e87a5Sjeremylt // Global-to-local 1152b730f8bSJeremy L Thompson PetscCall(VecZeroEntries(pr_restr_ctx->loc_vec_c)); 1162b730f8bSJeremy L Thompson PetscCall(DMGlobalToLocal(pr_restr_ctx->dmc, X, INSERT_VALUES, pr_restr_ctx->loc_vec_c)); 117e83e87a5Sjeremylt 118e83e87a5Sjeremylt // Setup libCEED vectors 119179e5961SZach Atkins PetscCall(VecReadP2C(pr_restr_ctx->loc_vec_c, &c_mem_type, pr_restr_ctx->ceed_vec_c)); 120179e5961SZach Atkins PetscCall(VecP2C(pr_restr_ctx->loc_vec_f, &f_mem_type, pr_restr_ctx->ceed_vec_f)); 121e83e87a5Sjeremylt 122e83e87a5Sjeremylt // Apply libCEED operator 1232b730f8bSJeremy L Thompson CeedOperatorApply(pr_restr_ctx->op_prolong, pr_restr_ctx->ceed_vec_c, pr_restr_ctx->ceed_vec_f, CEED_REQUEST_IMMEDIATE); 124e83e87a5Sjeremylt 125e83e87a5Sjeremylt // Restore PETSc vectors 126179e5961SZach Atkins PetscCall(VecReadC2P(pr_restr_ctx->ceed_vec_c, c_mem_type, pr_restr_ctx->loc_vec_c)); 127179e5961SZach Atkins PetscCall(VecC2P(pr_restr_ctx->ceed_vec_f, f_mem_type, pr_restr_ctx->loc_vec_f)); 128e83e87a5Sjeremylt 129e83e87a5Sjeremylt // Multiplicity 1302b730f8bSJeremy L Thompson PetscCall(VecPointwiseMult(pr_restr_ctx->loc_vec_f, pr_restr_ctx->loc_vec_f, pr_restr_ctx->mult_vec)); 131e83e87a5Sjeremylt 132e83e87a5Sjeremylt // Local-to-global 1332b730f8bSJeremy L Thompson PetscCall(VecZeroEntries(Y)); 1342b730f8bSJeremy L Thompson PetscCall(DMLocalToGlobal(pr_restr_ctx->dmf, pr_restr_ctx->loc_vec_f, ADD_VALUES, Y)); 135ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 136fd8f24faSSebastian Grimberg } 137e83e87a5Sjeremylt 138e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 139e83e87a5Sjeremylt // This function uses libCEED to compute the action of the restriction operator 140e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 141e83e87a5Sjeremylt PetscErrorCode MatMult_Restrict(Mat A, Vec X, Vec Y) { 142d4d45553Srezgarshakeri ProlongRestrContext pr_restr_ctx; 1439b072555Sjeremylt PetscMemType c_mem_type, f_mem_type; 144e83e87a5Sjeremylt 145e83e87a5Sjeremylt PetscFunctionBeginUser; 1462b730f8bSJeremy L Thompson PetscCall(MatShellGetContext(A, &pr_restr_ctx)); 147e83e87a5Sjeremylt 148e83e87a5Sjeremylt // Global-to-local 1492b730f8bSJeremy L Thompson PetscCall(VecZeroEntries(pr_restr_ctx->loc_vec_f)); 1502b730f8bSJeremy L Thompson PetscCall(DMGlobalToLocal(pr_restr_ctx->dmf, X, INSERT_VALUES, pr_restr_ctx->loc_vec_f)); 151e83e87a5Sjeremylt 152e83e87a5Sjeremylt // Multiplicity 1532b730f8bSJeremy L Thompson PetscCall(VecPointwiseMult(pr_restr_ctx->loc_vec_f, pr_restr_ctx->loc_vec_f, pr_restr_ctx->mult_vec)); 154e83e87a5Sjeremylt 155e83e87a5Sjeremylt // Setup libCEED vectors 156179e5961SZach Atkins PetscCall(VecReadP2C(pr_restr_ctx->loc_vec_f, &f_mem_type, pr_restr_ctx->ceed_vec_f)); 157179e5961SZach Atkins PetscCall(VecP2C(pr_restr_ctx->loc_vec_c, &c_mem_type, pr_restr_ctx->ceed_vec_c)); 158e83e87a5Sjeremylt 159e83e87a5Sjeremylt // Apply CEED operator 1602b730f8bSJeremy L Thompson CeedOperatorApply(pr_restr_ctx->op_restrict, pr_restr_ctx->ceed_vec_f, pr_restr_ctx->ceed_vec_c, CEED_REQUEST_IMMEDIATE); 161e83e87a5Sjeremylt 162e83e87a5Sjeremylt // Restore PETSc vectors 163179e5961SZach Atkins PetscCall(VecReadC2P(pr_restr_ctx->ceed_vec_f, f_mem_type, pr_restr_ctx->loc_vec_f)); 164179e5961SZach Atkins PetscCall(VecC2P(pr_restr_ctx->ceed_vec_c, c_mem_type, pr_restr_ctx->loc_vec_c)); 165e83e87a5Sjeremylt 166e83e87a5Sjeremylt // Local-to-global 1672b730f8bSJeremy L Thompson PetscCall(VecZeroEntries(Y)); 1682b730f8bSJeremy L Thompson PetscCall(DMLocalToGlobal(pr_restr_ctx->dmc, pr_restr_ctx->loc_vec_c, ADD_VALUES, Y)); 169ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 170fd8f24faSSebastian Grimberg } 171e83e87a5Sjeremylt 172e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 173e83e87a5Sjeremylt // This function calculates the error in the final solution 174e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 1752b730f8bSJeremy L Thompson PetscErrorCode ComputeL2Error(Vec X, PetscScalar *l2_error, OperatorApplyContext op_error_ctx) { 17638f32c05Srezgarshakeri Vec E; 17798285ab4SZach Atkins 178e83e87a5Sjeremylt PetscFunctionBeginUser; 17938f32c05Srezgarshakeri PetscCall(VecDuplicate(X, &E)); 18038f32c05Srezgarshakeri PetscCall(ApplyLocal_Ceed(X, E, op_error_ctx)); 181*78f7fce3SZach Atkins PetscCall(VecViewFromOptions(E, NULL, "-error_view")); 18238f32c05Srezgarshakeri PetscScalar error_sq = 1.0; 18338f32c05Srezgarshakeri PetscCall(VecSum(E, &error_sq)); 18438f32c05Srezgarshakeri *l2_error = sqrt(error_sq); 185*78f7fce3SZach Atkins PetscCall(VecDestroy(&E)); 186ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 187fd8f24faSSebastian Grimberg } 188e83e87a5Sjeremylt 189e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 190