[petsc-users] Two SNES on the same DM not working

Matteo Semplice matteo.semplice at uninsubria.it
Fri Nov 7 11:21:17 CST 2025


Il 07/11/25 02:10, Barry Smith ha scritto:
>
>
>> On Nov 6, 2025, at 4:11 AM, Stefano Zampini 
>> <stefano.zampini at gmail.com> wrote:
>>
>> Matteo
>>
>> eventually (and in some sense counterintuitively) the DM stores the 
>> information on the problem, not SNES.
>
>   "The information on the problem" here means the function you set 
> with SNESSetFunction, SNESSetJacobian etc. (and possibly other stuff, 
> I am not sure).

Oddly, sometimes the two SNES seems to work nevertheless, but after your 
anwers I will make sure that I explicitly DMClone when I need more that 
1 snes.

Matteo


>
>
>> 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> <mailto:bsmith at petsc.dev>
>>>     *Inviato:* mercoledì 5 novembre 2025 15:47
>>>     *A:* Samuele Ferri <sale987 at live.com> <mailto:sale987 at live.com>
>>>     *Cc:* petsc-users at mcs.anl.gov <petsc-users at mcs.anl.gov>
>>>     <mailto: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>
>>>>     <mailto: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
>
-- 
---
Professore Associato in Analisi Numerica
Dipartimento di Scienza e Alta Tecnologia
Università degli Studi dell'Insubria
Via Valleggio, 11 - Como
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20251107/d40dcb80/attachment-0001.html>


More information about the petsc-users mailing list