Matt, Matt, Matt, Sanjay, (1) is the only sane option. Here is an example taken from a code that I work with.
This simply has 3 fields with 12 ("stride", not a great name, should be "bs") dofs on each vertex in each field (2D Bell + 1D cubic Hermite). This uses ISCreateBlock, which you might want to use for dof (1,2) in your case. It lets, with stride = 2, input IS = [1,3] create an IS with [2,3,6,7] semantically. Thanks, Mark int matrix_solve:: setFieldSplitType() { // the global parameters PetscInt ierr, dofPerEnt,stride,k; int startDof, endDofPlusOne; int num_own_ent=m3dc1_mesh::instance()->num_own_ent[0], num_own_dof; m3dc1_field_getnumowndof(&fieldOrdering, &num_own_dof); if (num_own_ent) dofPerEnt = num_own_dof/num_own_ent; stride=dofPerEnt/3; //U 0->11, Omega 12->23, Chi 24->35 m3dc1_field_getowndofid (&fieldOrdering, &startDof, &endDofPlusOne); startDof=startDof/stride; // the 3 fields for PCFIELDSPLIT IS field0, field1, field2; PetscInt *idx0, *idx1, *idx2; ierr=PetscMalloc1(num_own_ent, &idx0); ierr=PetscMalloc1(num_own_ent, &idx1); ierr=PetscMalloc1(num_own_ent, &idx2); for (k=0; k<num_own_ent; k++) idx0[k]=k*dofPerEnt/stride + startDof; ierr=ISCreateBlock(PETSC_COMM_WORLD, stride, num_own_ent, idx0, PETSC_COPY_VALUES, &field0); for (k=0; k<num_own_ent; k++) idx1[k]=1+k*dofPerEnt/stride + startDof; ierr=ISCreateBlock(PETSC_COMM_WORLD, stride, num_own_ent, idx1, PETSC_COPY_VALUES, &field1); for (k=0; k<num_own_ent; k++) idx2[k]=2+k*dofPerEnt/stride + startDof; ierr=ISCreateBlock(PETSC_COMM_WORLD, stride, num_own_ent, idx2, PETSC_COPY_VALUES, &field2); PC pc; ierr= KSPAppendOptionsPrefix(*ksp,"fs_"); // ksp is a global here ierr=KSPGetPC(*ksp, &pc); ierr=PCSetType(pc, PCFIELDSPLIT); ierr=PCFieldSplitSetIS(pc, NULL, field0); ierr=PCFieldSplitSetIS(pc, NULL, field1); ierr=PCFieldSplitSetIS(pc, NULL, field2); ierr=PetscFree(idx0);PetscCall <https://urldefense.us/v3/__https://petsc.org/main/manualpages/Sys/PetscCall/__;!!G_uCfscf7eWS!c_nKrPbKpTddk11qYmEtY65UqhTbG4LXm7rfRLNAprFTA0x4y_NfBtBIEhOMant3sxPS91A_TgyDkqZ9gefqEq4$ >(ISDestroy <https://urldefense.us/v3/__https://petsc.org/main/manualpages/IS/ISDestroy/__;!!G_uCfscf7eWS!c_nKrPbKpTddk11qYmEtY65UqhTbG4LXm7rfRLNAprFTA0x4y_NfBtBIEhOMant3sxPS91A_TgyDkqZ9VDKwi_8$ >(&field0));PetscCall <https://urldefense.us/v3/__https://petsc.org/main/manualpages/Sys/PetscCall/__;!!G_uCfscf7eWS!c_nKrPbKpTddk11qYmEtY65UqhTbG4LXm7rfRLNAprFTA0x4y_NfBtBIEhOMant3sxPS91A_TgyDkqZ9gefqEq4$ >(ISDestroy <https://urldefense.us/v3/__https://petsc.org/main/manualpages/IS/ISDestroy/__;!!G_uCfscf7eWS!c_nKrPbKpTddk11qYmEtY65UqhTbG4LXm7rfRLNAprFTA0x4y_NfBtBIEhOMant3sxPS91A_TgyDkqZ9VDKwi_8$ >(&field1));PetscCall <https://urldefense.us/v3/__https://petsc.org/main/manualpages/Sys/PetscCall/__;!!G_uCfscf7eWS!c_nKrPbKpTddk11qYmEtY65UqhTbG4LXm7rfRLNAprFTA0x4y_NfBtBIEhOMant3sxPS91A_TgyDkqZ9gefqEq4$ >(ISDestroy <https://urldefense.us/v3/__https://petsc.org/main/manualpages/IS/ISDestroy/__;!!G_uCfscf7eWS!c_nKrPbKpTddk11qYmEtY65UqhTbG4LXm7rfRLNAprFTA0x4y_NfBtBIEhOMant3sxPS91A_TgyDkqZ9VDKwi_8$ >(&field2)); ierr=PetscFree(idx1); ierr=PetscFree(idx2); fsSet=1; return 0; } On Thu, Apr 3, 2025 at 8:57 AM Matthew Knepley <knep...@gmail.com> wrote: > On Thu, Apr 3, 2025 at 12:11 AM Sanjay Govindjee via petsc-users < > petsc-users@mcs.anl.gov> wrote: > >> We would like to solve an FEA problem (unstructured grid) where the nodes >> on the elements have different dofs. For example the corner nodes have >> only dof 0 and then mid-side nodes have dofs 0,1,2 (think 8 node >> serendipity element). This is a multi-physics problem so we are looking to >> use the fieldsplit features to pre-condition and solve. Is there a simple >> example of this type of usage in the src that we can try to mimic? >> >> I presume this will take programming as opposed to just setting command >> line options. >> > > It will take a little programming, but not much. Here is the idea. > FieldSplit needs to know what dofs belong to what field. There are a couple > of ways to do this, at different levels of abstraction. > > 1. Low level > > You can explicitly makes lists of the dofs in each field, as an IS, and > call > https://urldefense.us/v3/__https://petsc.org/main/manualpages/PC/PCFieldSplitSetIS/__;!!G_uCfscf7eWS!c_nKrPbKpTddk11qYmEtY65UqhTbG4LXm7rfRLNAprFTA0x4y_NfBtBIEhOMant3sxPS91A_TgyDkqZ9-jY5Sfg$ > > <https://urldefense.us/v3/__https://petsc.org/main/manualpages/PC/PCFieldSplitSetIS/__;!!G_uCfscf7eWS!aMROjbrPD3RYXMpO8mIii7q8eXZX1uN-6F6-g_jcNLLXGCgYPt2JEDkIIQCHs_vNBhhxsiwQJaz57ydxKyWe$> > for each field. This is not very flexible, but the easiest to understand. > > 2. Intermediate level > > You can make a DMShell, and then make a PetscSection, that gives the > number of dofs on each vertex and edge. Then call KSPSetDM() or > SNESSetDM(), and you can do nested fieldsplits from the command line. This > also retains a connection between the topology and the data layout, but you > have to deal with that pesky DM object. > > 3. High level > > You can use a DMPlex to represent your grid and a PetscFE to represent the > discretization, and then layout is done automatically, and nested > fieldsplits can be done from the command line. I am not 100% sure PetscFE > can represent what you want, but you can always call DMPlexCreateSection() > by hand to make the PetscSection. > > Thanks, > > Matt > > >> -sanjay >> >> > > -- > What most experimenters take for granted before they begin their > experiments is infinitely more interesting than any results to which their > experiments lead. > -- Norbert Wiener > > https://urldefense.us/v3/__https://www.cse.buffalo.edu/*knepley/__;fg!!G_uCfscf7eWS!c_nKrPbKpTddk11qYmEtY65UqhTbG4LXm7rfRLNAprFTA0x4y_NfBtBIEhOMant3sxPS91A_TgyDkqZ9zTSheMM$ > > <https://urldefense.us/v3/__http://www.cse.buffalo.edu/*knepley/__;fg!!G_uCfscf7eWS!aMROjbrPD3RYXMpO8mIii7q8eXZX1uN-6F6-g_jcNLLXGCgYPt2JEDkIIQCHs_vNBhhxsiwQJaz57-FUThx2$> >