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

Reply via email to