This is not supported. Duplicate your DM.
> On Nov 5, 2025, at 9:17 AM, Samuele Ferri <[email protected]> wrote:
>
> Dear petsc users,
>
> in petsc version 3.24, I'm trying to create two snes over the same DM, but
> with different functions and jacobians. Despite making different calls to
> SNESSetFunction it happens the second snes uses the same function of the
> first.
> Can you help me finding the problem, please?
>
> Here below there is a minimal working example showing the issue:
>
> static char help[] = "Test SNES.\n";
> #include <petscsys.h>
> #include <petscdmda.h>
> #include <petscsnes.h>
>
> PetscErrorCode Jac_1(SNES snes, Vec x, Mat J, Mat B, void *){
> PetscFunctionBegin;
> printf("Jac 1\n");
> PetscFunctionReturn(PETSC_SUCCESS);
> }
>
> PetscErrorCode Function_1(SNES snes, Vec x, Vec f, void *){
> PetscFunctionBegin;
> printf("Function 1\n");
> PetscFunctionReturn(PETSC_SUCCESS);
> }
>
> PetscErrorCode Jac_2(SNES snes, Vec x, Mat J, Mat B, void *){
> PetscFunctionBegin;
> printf("Jac 2\n");
> PetscFunctionReturn(PETSC_SUCCESS);
> }
>
> PetscErrorCode Function_2(SNES snes, Vec x, Vec f, void *){
> PetscFunctionBegin;
> printf("Function 2\n");
> PetscFunctionReturn(PETSC_SUCCESS);
> }
>
> int main(int argc, char **argv) {
>
> PetscFunctionBeginUser;
> PetscCall(PetscInitialize(&argc, &argv, NULL, help));
>
> DM dm;
> PetscCall(DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, 100, 1, 1,
> NULL, &dm));
> PetscCall(DMSetFromOptions(dm));
> PetscCall(DMSetUp(dm));
>
> SNES snes1, snes2;
> Vec r1,r2;
> Mat J1, J2;
>
> PetscCall(DMCreateGlobalVector(dm, &r1));
> PetscCall(DMCreateGlobalVector(dm, &r2))
> PetscCall(DMCreateMatrix(dm, &J1));
> PetscCall(DMCreateMatrix(dm, &J2));
>
> PetscCall(SNESCreate(PETSC_COMM_WORLD, &snes1));
> PetscCall(SNESCreate(PETSC_COMM_WORLD, &snes2));
> PetscCall(SNESSetType(snes1, SNESNEWTONLS));
> PetscCall(SNESSetType(snes2, SNESNEWTONLS));
> PetscCall(SNESSetFromOptions(snes1));
> PetscCall(SNESSetFromOptions(snes2));
> PetscCall(SNESSetFunction(snes1, r1, Function_1, NULL));
> PetscCall(SNESSetFunction(snes2, r2, Function_2, NULL));
> PetscCall(SNESSetJacobian(snes1, J1, J1, Jac_1, NULL));
> PetscCall(SNESSetJacobian(snes2, J2, J2, Jac_2, NULL));
> PetscCall(SNESSetDM(snes1, dm));
> PetscCall(SNESSetDM(snes2, dm));
>
> PetscCall(SNESSolve(snes1, NULL, NULL));
> PetscCall(SNESSolve(snes2, NULL, NULL));
>
> printf("snes1 %p; snes2 %p\n", snes1, snes2);
>
> SNESFunctionFn *p;
> PetscCall(SNESGetFunction(snes1, NULL, &p, NULL));
> printf("snes1: pointer %p, true function %p\n", *p, Function_1);
> PetscCall(SNESGetFunction(snes2, NULL, &p, NULL));
> printf("snes2: pointer %p, true function %p\n", *p, Function_2);
>
> PetscCall(PetscFinalize());
> PetscFunctionReturn(PETSC_SUCCESS);
> }