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]>
*Inviato:* mercoledì 5 novembre 2025 15:47
*A:* Samuele Ferri <[email protected]>
*Cc:* [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]> 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

Reply via email to