> 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). > 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] <mailto:[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] <mailto:[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] <mailto:[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
