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);
> }

Reply via email to