Il 07/11/25 02:10, Barry Smith ha scritto:


On Nov 6, 2025, at 4:11 AM, Stefano Zampini <[email protected]> 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 <[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]> <mailto:[email protected]>
    *Inviato:* mercoledì 5 novembre 2025 15:47
    *A:* Samuele Ferri <[email protected]> <mailto:[email protected]>
    *Cc:* [email protected] <[email protected]>
    <mailto:[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]>
    <mailto:[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

--
---
Professore Associato in Analisi Numerica
Dipartimento di Scienza e Alta Tecnologia
Università degli Studi dell'Insubria
Via Valleggio, 11 - Como

Reply via email to