Actual source code: dmplexsnesceed.c
1: #include <petsc/private/dmpleximpl.h>
2: #include <petsc/private/snesimpl.h>
3: #include <petscds.h>
4: #include <petsc/private/petscimpl.h>
5: #include <petsc/private/petscfeimpl.h>
6: #include <petscdmceed.h>
7: #include <petscdmplexceed.h>
9: /*@C
10: DMPlexSNESComputeResidualCEED - Assemble the local residual for a `SNES` on a `DMPLEX` using the libCEED operator attached to the `DM`
12: Collective
14: Input Parameters:
15: + dm - the `DMPLEX` for which libCEED operators have been created by `DMCeedCreate()`
16: . locX - local solution vector including ghost values
17: - ctx - application context (unused)
19: Output Parameter:
20: . locF - local residual vector to be assembled
22: Level: developer
24: Note:
25: This is normally installed as the `SNES` local residual callback via `DMSNESSetFunctionLocal()` when using libCEED for the finite-element evaluation.
27: .seealso: [](ch_snes), `SNES`, `DMPLEX`, `DMCeedCreate()`, `DMSNESSetFunctionLocal()`, `DMPlexTSComputeRHSFunctionFVMCEED()`
28: @*/
29: PetscErrorCode DMPlexSNESComputeResidualCEED(DM dm, Vec locX, Vec locF, PetscCtx ctx)
30: {
31: Ceed ceed;
32: DMCeed sd = dm->dmceed;
33: CeedVector clocX, clocF;
35: PetscFunctionBegin;
36: PetscCall(DMGetCeed(dm, &ceed));
37: PetscCheck(sd, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DM has no CEED data. Call DMCeedCreate() before computing the residual.");
38: PetscCall(DMCeedComputeGeometry(dm, sd));
40: PetscCall(VecGetCeedVectorRead(locX, ceed, &clocX));
41: PetscCall(VecGetCeedVector(locF, ceed, &clocF));
42: PetscCallCEED(CeedOperatorApplyAdd(sd->op, clocX, clocF, CEED_REQUEST_IMMEDIATE));
43: PetscCall(VecRestoreCeedVectorRead(locX, &clocX));
44: PetscCall(VecRestoreCeedVector(locF, &clocF));
46: {
47: DM_Plex *mesh = (DM_Plex *)dm->data;
49: if (mesh->printFEM) {
50: PetscSection section;
51: Vec locFbc;
52: PetscInt pStart, pEnd, p, maxDof;
53: PetscScalar *zeroes;
55: PetscCall(DMGetLocalSection(dm, §ion));
56: PetscCall(VecDuplicate(locF, &locFbc));
57: PetscCall(VecCopy(locF, locFbc));
58: PetscCall(PetscSectionGetChart(section, &pStart, &pEnd));
59: PetscCall(PetscSectionGetMaxDof(section, &maxDof));
60: PetscCall(PetscCalloc1(maxDof, &zeroes));
61: for (p = pStart; p < pEnd; ++p) PetscCall(VecSetValuesSection(locFbc, section, p, zeroes, INSERT_BC_VALUES));
62: PetscCall(PetscFree(zeroes));
63: PetscCall(DMPrintLocalVec(dm, "Residual", mesh->printTol, locFbc));
64: PetscCall(VecDestroy(&locFbc));
65: }
66: }
67: PetscFunctionReturn(PETSC_SUCCESS);
68: }