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