Matteo eventually (and in some sense counterintuitively) the DM stores the information on the problem, not SNES. See the snippet below to make things more clear
SNESSetDM(snes1,dm) SNESSetFunction(snes1,F) SNESSolve(snes1) // Solves F(x)=0 SNESSetDM(snes2,dm) SNESSetFunction(snes2,G) SNESSolve(snes2) // Solves G(x)=0 SNESSolve(snes1) // Solves G(x), not F(x)!! If you have a plex you can call DMClone(dm,dm2) and set a new section on dm2 to be used on snes2 (the mesh won't be duplicated, only the problem dependent part) I guess you can follow the same approach with a DMDA, it should work. If not, you may need to call DMDuplicate on the DMDA. Il giorno gio 6 nov 2025 alle ore 11:19 Matteo Semplice via petsc-users < [email protected]> ha scritto: > Dear Barry, > > sorry for jumping into this. > > > I am wondering if your reply is related to DMDA or to DM in general. I > have at least one code where I do something similar to what Samuele did in > his sample code: create a DMPlex, create a section on this DMPlex, create > two SNES solving for Vecs defined on that same section and attach to each > of them a different SNESFunction and SNESJacobian (one solves a predictor > and the other is a corrector). Everything seems fine, but I am wondering if > that code is somewhat weak and should be changed by DMCloning the plex as > you suggested to Samuele. > > > Thanks > > Matteo > > > On 06/11/2025 07:49, Samuele Ferri wrote: > > > [email protected] sembra simile a un utente che in precedenza ti ha > inviato un messaggio di posta elettronica, ma potrebbe non essere lo > stesso. Scopri perché potrebbe trattarsi di un rischio > <https://urldefense.us/v3/__https://aka.ms/LearnAboutSenderIdentification__;!!G_uCfscf7eWS!d2x1h3Pt9OqhfeBcqW8pR0dbGy3bRw6bM-p0DxGAaY0CXWkqH3lpsuXiob9mOqfsy-aRVJXUig3819n2CWpYyFn4FDaTAWRxNDXZsA$> > > Dear Barry, > > thank you for your reply. Now everything works fine. > > Best regards > Samuele > ------------------------------ > *Da:* Barry Smith <[email protected]> <[email protected]> > *Inviato:* mercoledì 5 novembre 2025 15:47 > *A:* Samuele Ferri <[email protected]> <[email protected]> > *Cc:* [email protected] <[email protected]> > <[email protected]> > *Oggetto:* Re: [petsc-users] Two SNES on the same DM not working > > > This is not supported. Duplicate your DM. > > On Nov 5, 2025, at 9:17 AM, Samuele Ferri <[email protected]> > <[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); > } > > > -- > Prof. Matteo Semplice > Università degli Studi dell’Insubria > Dipartimento di Scienza e Alta Tecnologia – DiSAT > Professore Associato > Via Valleggio, 11 – 22100 Como (CO) – Italia > tel.: +39 031 2386316 > > -- Stefano
