[petsc-users] R: Two SNES on the same DM not working
Stefano Zampini
stefano.zampini at gmail.com
Thu Nov 6 03:11:26 CST 2025
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 <
petsc-users at mcs.anl.gov> 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:
>
>
> sale987 at live.com 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 <bsmith at petsc.dev> <bsmith at petsc.dev>
> *Inviato:* mercoledì 5 novembre 2025 15:47
> *A:* Samuele Ferri <sale987 at live.com> <sale987 at live.com>
> *Cc:* petsc-users at mcs.anl.gov <petsc-users at mcs.anl.gov>
> <petsc-users at mcs.anl.gov>
> *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 <sale987 at live.com>
> <sale987 at live.com> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20251106/9843bf82/attachment-0001.html>
More information about the petsc-users
mailing list