1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2af0996ceSBarry Smith #include <petsc/private/isimpl.h> 30c312b8eSJed Brown #include <petscsf.h> 4a9fb6443SMatthew G. Knepley #include <petscds.h> 5cb1e1211SMatthew G Knepley 6cb1e1211SMatthew G Knepley #undef __FUNCT__ 776185916SToby Isaac #define __FUNCT__ "DMPlexComputeAnchorAdjacencies" 876185916SToby Isaac /* get adjacencies due to point-to-point constraints that can't be found with DMPlexGetAdjacency() */ 9e101f074SMatthew G. Knepley static PetscErrorCode DMPlexComputeAnchorAdjacencies(DM dm, PetscBool useCone, PetscBool useClosure, PetscSection *anchorSectionAdj, PetscInt *anchorAdj[]) 1076185916SToby Isaac { 1176185916SToby Isaac PetscInt pStart, pEnd; 12e101f074SMatthew G. Knepley PetscSection section, sectionGlobal, adjSec, aSec; 1376185916SToby Isaac IS aIS; 1476185916SToby Isaac PetscErrorCode ierr; 1576185916SToby Isaac 1676185916SToby Isaac PetscFunctionBegin; 17e101f074SMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 18e101f074SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 1976185916SToby Isaac ierr = PetscSectionCreate(PetscObjectComm((PetscObject) section), &adjSec);CHKERRQ(ierr); 2076185916SToby Isaac ierr = PetscSectionGetChart(section,&pStart,&pEnd);CHKERRQ(ierr); 2176185916SToby Isaac ierr = PetscSectionSetChart(adjSec,pStart,pEnd);CHKERRQ(ierr); 2276185916SToby Isaac 23a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 2476185916SToby Isaac if (aSec) { 2576185916SToby Isaac const PetscInt *anchors; 2676185916SToby Isaac PetscInt p, q, a, aSize, *offsets, aStart, aEnd, *inverse, iSize, *adj, adjSize; 2776185916SToby Isaac PetscInt *tmpAdjP = NULL, *tmpAdjQ = NULL; 2876185916SToby Isaac PetscSection inverseSec; 2976185916SToby Isaac 3076185916SToby Isaac /* invert the constraint-to-anchor map */ 3176185916SToby Isaac ierr = PetscSectionCreate(PetscObjectComm((PetscObject)aSec),&inverseSec);CHKERRQ(ierr); 3276185916SToby Isaac ierr = PetscSectionSetChart(inverseSec,pStart,pEnd);CHKERRQ(ierr); 3376185916SToby Isaac ierr = ISGetLocalSize(aIS, &aSize);CHKERRQ(ierr); 3476185916SToby Isaac ierr = ISGetIndices(aIS, &anchors);CHKERRQ(ierr); 3576185916SToby Isaac 3676185916SToby Isaac for (p = 0; p < aSize; p++) { 3776185916SToby Isaac PetscInt a = anchors[p]; 3876185916SToby Isaac 3976185916SToby Isaac ierr = PetscSectionAddDof(inverseSec,a,1);CHKERRQ(ierr); 4076185916SToby Isaac } 4176185916SToby Isaac ierr = PetscSectionSetUp(inverseSec);CHKERRQ(ierr); 4276185916SToby Isaac ierr = PetscSectionGetStorageSize(inverseSec,&iSize);CHKERRQ(ierr); 4376185916SToby Isaac ierr = PetscMalloc1(iSize,&inverse);CHKERRQ(ierr); 4476185916SToby Isaac ierr = PetscCalloc1(pEnd-pStart,&offsets);CHKERRQ(ierr); 4576185916SToby Isaac ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); 4676185916SToby Isaac for (p = aStart; p < aEnd; p++) { 4776185916SToby Isaac PetscInt dof, off; 4876185916SToby Isaac 4976185916SToby Isaac ierr = PetscSectionGetDof(aSec, p, &dof);CHKERRQ(ierr); 5076185916SToby Isaac ierr = PetscSectionGetOffset(aSec, p, &off);CHKERRQ(ierr); 5176185916SToby Isaac 5276185916SToby Isaac for (q = 0; q < dof; q++) { 5376185916SToby Isaac PetscInt iOff; 5476185916SToby Isaac 5576185916SToby Isaac a = anchors[off + q]; 5676185916SToby Isaac ierr = PetscSectionGetOffset(inverseSec, a, &iOff);CHKERRQ(ierr); 5776185916SToby Isaac inverse[iOff + offsets[a-pStart]++] = p; 5876185916SToby Isaac } 5976185916SToby Isaac } 6076185916SToby Isaac ierr = ISRestoreIndices(aIS, &anchors);CHKERRQ(ierr); 6176185916SToby Isaac ierr = PetscFree(offsets);CHKERRQ(ierr); 6276185916SToby Isaac 6376185916SToby Isaac /* construct anchorAdj and adjSec 6476185916SToby Isaac * 6576185916SToby Isaac * loop over anchors: 6676185916SToby Isaac * construct anchor adjacency 6776185916SToby Isaac * loop over constrained: 6876185916SToby Isaac * construct constrained adjacency 6976185916SToby Isaac * if not in anchor adjacency, add to dofs 7076185916SToby Isaac * setup adjSec, allocate anchorAdj 7176185916SToby Isaac * loop over anchors: 7276185916SToby Isaac * construct anchor adjacency 7376185916SToby Isaac * loop over constrained: 7476185916SToby Isaac * construct constrained adjacency 7576185916SToby Isaac * if not in anchor adjacency 7676185916SToby Isaac * if not already in list, put in list 7776185916SToby Isaac * sort, unique, reduce dof count 7876185916SToby Isaac * optional: compactify 7976185916SToby Isaac */ 8076185916SToby Isaac for (p = pStart; p < pEnd; p++) { 8176185916SToby Isaac PetscInt iDof, iOff, i, r, s, numAdjP = PETSC_DETERMINE; 8276185916SToby Isaac 8376185916SToby Isaac ierr = PetscSectionGetDof(inverseSec,p,&iDof);CHKERRQ(ierr); 8476185916SToby Isaac if (!iDof) continue; 8576185916SToby Isaac ierr = PetscSectionGetOffset(inverseSec,p,&iOff);CHKERRQ(ierr); 86a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacency_Internal(dm,p,useCone,useClosure,PETSC_TRUE,&numAdjP,&tmpAdjP);CHKERRQ(ierr); 8776185916SToby Isaac for (i = 0; i < iDof; i++) { 8876185916SToby Isaac PetscInt iNew = 0, qAdj, qAdjDof, qAdjCDof, numAdjQ = PETSC_DETERMINE; 8976185916SToby Isaac 9076185916SToby Isaac q = inverse[iOff + i]; 91a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacency_Internal(dm,q,useCone,useClosure,PETSC_TRUE,&numAdjQ,&tmpAdjQ);CHKERRQ(ierr); 9276185916SToby Isaac for (r = 0; r < numAdjQ; r++) { 9376185916SToby Isaac qAdj = tmpAdjQ[r]; 9476185916SToby Isaac if ((qAdj < pStart) || (qAdj >= pEnd)) continue; 9576185916SToby Isaac for (s = 0; s < numAdjP; s++) { 9676185916SToby Isaac if (qAdj == tmpAdjP[s]) break; 9776185916SToby Isaac } 9876185916SToby Isaac if (s < numAdjP) continue; 9976185916SToby Isaac ierr = PetscSectionGetDof(section,qAdj,&qAdjDof);CHKERRQ(ierr); 10076185916SToby Isaac ierr = PetscSectionGetConstraintDof(section,qAdj,&qAdjCDof);CHKERRQ(ierr); 10176185916SToby Isaac iNew += qAdjDof - qAdjCDof; 10276185916SToby Isaac } 10376185916SToby Isaac ierr = PetscSectionAddDof(adjSec,p,iNew);CHKERRQ(ierr); 10476185916SToby Isaac } 10576185916SToby Isaac } 10676185916SToby Isaac 10776185916SToby Isaac ierr = PetscSectionSetUp(adjSec);CHKERRQ(ierr); 10876185916SToby Isaac ierr = PetscSectionGetStorageSize(adjSec,&adjSize);CHKERRQ(ierr); 10976185916SToby Isaac ierr = PetscMalloc1(adjSize,&adj);CHKERRQ(ierr); 11076185916SToby Isaac 11176185916SToby Isaac for (p = pStart; p < pEnd; p++) { 11276185916SToby Isaac PetscInt iDof, iOff, i, r, s, aOff, aOffOrig, aDof, numAdjP = PETSC_DETERMINE; 11376185916SToby Isaac 11476185916SToby Isaac ierr = PetscSectionGetDof(inverseSec,p,&iDof);CHKERRQ(ierr); 11576185916SToby Isaac if (!iDof) continue; 11676185916SToby Isaac ierr = PetscSectionGetOffset(inverseSec,p,&iOff);CHKERRQ(ierr); 117a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacency_Internal(dm,p,useCone,useClosure,PETSC_TRUE,&numAdjP,&tmpAdjP);CHKERRQ(ierr); 11876185916SToby Isaac ierr = PetscSectionGetDof(adjSec,p,&aDof);CHKERRQ(ierr); 11976185916SToby Isaac ierr = PetscSectionGetOffset(adjSec,p,&aOff);CHKERRQ(ierr); 12076185916SToby Isaac aOffOrig = aOff; 12176185916SToby Isaac for (i = 0; i < iDof; i++) { 12276185916SToby Isaac PetscInt qAdj, qAdjDof, qAdjCDof, qAdjOff, nd, numAdjQ = PETSC_DETERMINE; 12376185916SToby Isaac 12476185916SToby Isaac q = inverse[iOff + i]; 125a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacency_Internal(dm,q,useCone,useClosure,PETSC_TRUE,&numAdjQ,&tmpAdjQ);CHKERRQ(ierr); 12676185916SToby Isaac for (r = 0; r < numAdjQ; r++) { 12776185916SToby Isaac qAdj = tmpAdjQ[r]; 12876185916SToby Isaac if ((qAdj < pStart) || (qAdj >= pEnd)) continue; 12976185916SToby Isaac for (s = 0; s < numAdjP; s++) { 13076185916SToby Isaac if (qAdj == tmpAdjP[s]) break; 13176185916SToby Isaac } 13276185916SToby Isaac if (s < numAdjP) continue; 13376185916SToby Isaac ierr = PetscSectionGetDof(section,qAdj,&qAdjDof);CHKERRQ(ierr); 13476185916SToby Isaac ierr = PetscSectionGetConstraintDof(section,qAdj,&qAdjCDof);CHKERRQ(ierr); 13576185916SToby Isaac ierr = PetscSectionGetOffset(sectionGlobal,qAdj,&qAdjOff);CHKERRQ(ierr); 13676185916SToby Isaac for (nd = 0; nd < qAdjDof-qAdjCDof; ++nd) { 13776185916SToby Isaac adj[aOff++] = (qAdjOff < 0 ? -(qAdjOff+1) : qAdjOff) + nd; 13876185916SToby Isaac } 13976185916SToby Isaac } 14076185916SToby Isaac } 14176185916SToby Isaac ierr = PetscSortRemoveDupsInt(&aDof,&adj[aOffOrig]);CHKERRQ(ierr); 14276185916SToby Isaac ierr = PetscSectionSetDof(adjSec,p,aDof);CHKERRQ(ierr); 14376185916SToby Isaac } 14476185916SToby Isaac *anchorAdj = adj; 14576185916SToby Isaac 14676185916SToby Isaac /* clean up */ 14776185916SToby Isaac ierr = PetscSectionDestroy(&inverseSec);CHKERRQ(ierr); 14876185916SToby Isaac ierr = PetscFree(inverse);CHKERRQ(ierr); 14976185916SToby Isaac ierr = PetscFree(tmpAdjP);CHKERRQ(ierr); 15076185916SToby Isaac ierr = PetscFree(tmpAdjQ);CHKERRQ(ierr); 15176185916SToby Isaac } 15276185916SToby Isaac else { 15376185916SToby Isaac *anchorAdj = NULL; 15476185916SToby Isaac ierr = PetscSectionSetUp(adjSec);CHKERRQ(ierr); 15576185916SToby Isaac } 15676185916SToby Isaac *anchorSectionAdj = adjSec; 15776185916SToby Isaac PetscFunctionReturn(0); 15876185916SToby Isaac } 15976185916SToby Isaac 16076185916SToby Isaac #undef __FUNCT__ 161a9fb6443SMatthew G. Knepley #define __FUNCT__ "DMPlexCreateAdjacencySection_Static" 162e101f074SMatthew G. Knepley PetscErrorCode DMPlexCreateAdjacencySection_Static(DM dm, PetscInt bs, PetscSF sfDof, PetscBool useCone, PetscBool useClosure, PetscBool useAnchors, PetscSection *sA, PetscInt **colIdx) 163cb1e1211SMatthew G Knepley { 164cb1e1211SMatthew G Knepley MPI_Comm comm; 165a9fb6443SMatthew G. Knepley PetscMPIInt size; 166a9fb6443SMatthew G. Knepley PetscBool doCommLocal, doComm, debug = PETSC_FALSE; 167a9fb6443SMatthew G. Knepley PetscSF sf, sfAdj; 168e101f074SMatthew G. Knepley PetscSection section, sectionGlobal, leafSectionAdj, rootSectionAdj, sectionAdj, anchorSectionAdj; 169a9fb6443SMatthew G. Knepley PetscInt nroots, nleaves, l, p, r; 170cb1e1211SMatthew G Knepley const PetscInt *leaves; 171cb1e1211SMatthew G Knepley const PetscSFNode *remotes; 172cb1e1211SMatthew G Knepley PetscInt dim, pStart, pEnd, numDof, globalOffStart, globalOffEnd, numCols; 1738821704fSMatthew G. Knepley PetscInt *tmpAdj = NULL, *adj, *rootAdj, *anchorAdj = NULL, *cols, *remoteOffsets; 17470034214SMatthew G. Knepley PetscInt adjSize; 175cb1e1211SMatthew G Knepley PetscErrorCode ierr; 176cb1e1211SMatthew G Knepley 177cb1e1211SMatthew G Knepley PetscFunctionBegin; 178cb1e1211SMatthew G Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 179cb1e1211SMatthew G Knepley ierr = PetscOptionsGetBool(NULL, "-dm_view_preallocation", &debug, NULL);CHKERRQ(ierr); 180cb1e1211SMatthew G Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 181c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 182cb1e1211SMatthew G Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 183e101f074SMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 184e101f074SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 18547a6104aSMatthew G. Knepley ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 18647a6104aSMatthew G. Knepley doCommLocal = (size > 1) && (nroots >= 0) ? PETSC_TRUE : PETSC_FALSE; 187*b2566f29SBarry Smith ierr = MPIU_Allreduce(&doCommLocal, &doComm, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr); 188cb1e1211SMatthew G Knepley /* Create section for dof adjacency (dof ==> # adj dof) */ 189cb1e1211SMatthew G Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 190cb1e1211SMatthew G Knepley ierr = PetscSectionGetStorageSize(section, &numDof);CHKERRQ(ierr); 191cb1e1211SMatthew G Knepley ierr = PetscSectionCreate(comm, &leafSectionAdj);CHKERRQ(ierr); 192cb1e1211SMatthew G Knepley ierr = PetscSectionSetChart(leafSectionAdj, 0, numDof);CHKERRQ(ierr); 193cb1e1211SMatthew G Knepley ierr = PetscSectionCreate(comm, &rootSectionAdj);CHKERRQ(ierr); 194cb1e1211SMatthew G Knepley ierr = PetscSectionSetChart(rootSectionAdj, 0, numDof);CHKERRQ(ierr); 195cb1e1211SMatthew G Knepley /* Fill in the ghost dofs on the interface */ 196cb1e1211SMatthew G Knepley ierr = PetscSFGetGraph(sf, NULL, &nleaves, &leaves, &remotes);CHKERRQ(ierr); 197cb1e1211SMatthew G Knepley /* 198964bf7afSMatthew G. Knepley section - maps points to (# dofs, local dofs) 199964bf7afSMatthew G. Knepley sectionGlobal - maps points to (# dofs, global dofs) 200964bf7afSMatthew G. Knepley leafSectionAdj - maps unowned local dofs to # adj dofs 201964bf7afSMatthew G. Knepley rootSectionAdj - maps owned local dofs to # adj dofs 202964bf7afSMatthew G. Knepley adj - adj global dofs indexed by leafSectionAdj 203964bf7afSMatthew G. Knepley rootAdj - adj global dofs indexed by rootSectionAdj 204964bf7afSMatthew G. Knepley sf - describes shared points across procs 205964bf7afSMatthew G. Knepley sfDof - describes shared dofs across procs 206964bf7afSMatthew G. Knepley sfAdj - describes shared adjacent dofs across procs 207cb1e1211SMatthew G Knepley ** The bootstrapping process involves six rounds with similar structure of visiting neighbors of each point. 20876185916SToby Isaac (0). If there are point-to-point constraints, add the adjacencies of constrained points to anchors in anchorAdj 20976185916SToby Isaac (This is done in DMPlexComputeAnchorAdjacencies()) 210cb1e1211SMatthew G Knepley 1. Visit unowned points on interface, count adjacencies placing in leafSectionAdj 211cb1e1211SMatthew G Knepley Reduce those counts to rootSectionAdj (now redundantly counting some interface points) 212cb1e1211SMatthew G Knepley 2. Visit owned points on interface, count adjacencies placing in rootSectionAdj 213cb1e1211SMatthew G Knepley Create sfAdj connecting rootSectionAdj and leafSectionAdj 214cb1e1211SMatthew G Knepley 3. Visit unowned points on interface, write adjacencies to adj 215cb1e1211SMatthew G Knepley Gather adj to rootAdj (note that there is redundancy in rootAdj when multiple procs find the same adjacencies) 216cb1e1211SMatthew G Knepley 4. Visit owned points on interface, write adjacencies to rootAdj 217cb1e1211SMatthew G Knepley Remove redundancy in rootAdj 218cb1e1211SMatthew G Knepley ** The last two traversals use transitive closure 219cb1e1211SMatthew G Knepley 5. Visit all owned points in the subdomain, count dofs for each point (sectionAdj) 220cb1e1211SMatthew G Knepley Allocate memory addressed by sectionAdj (cols) 221cb1e1211SMatthew G Knepley 6. Visit all owned points in the subdomain, insert dof adjacencies into cols 222cb1e1211SMatthew G Knepley ** Knowing all the column adjacencies, check ownership and sum into dnz and onz 223cb1e1211SMatthew G Knepley */ 224e101f074SMatthew G. Knepley ierr = DMPlexComputeAnchorAdjacencies(dm, useCone, useClosure, &anchorSectionAdj, &anchorAdj);CHKERRQ(ierr); 225cb1e1211SMatthew G Knepley for (l = 0; l < nleaves; ++l) { 22676185916SToby Isaac PetscInt dof, off, d, q, anDof; 22770034214SMatthew G. Knepley PetscInt p = leaves[l], numAdj = PETSC_DETERMINE; 228cb1e1211SMatthew G Knepley 229fb47e2feSMatthew G. Knepley if ((p < pStart) || (p >= pEnd)) continue; 230cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 231cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); 232a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacency_Internal(dm, p, useCone, useClosure, useAnchors, &numAdj, &tmpAdj);CHKERRQ(ierr); 233cb1e1211SMatthew G Knepley for (q = 0; q < numAdj; ++q) { 234cb1e1211SMatthew G Knepley const PetscInt padj = tmpAdj[q]; 235cb1e1211SMatthew G Knepley PetscInt ndof, ncdof; 236cb1e1211SMatthew G Knepley 237cb1e1211SMatthew G Knepley if ((padj < pStart) || (padj >= pEnd)) continue; 238cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, padj, &ndof);CHKERRQ(ierr); 239cb1e1211SMatthew G Knepley ierr = PetscSectionGetConstraintDof(section, padj, &ncdof);CHKERRQ(ierr); 240cb1e1211SMatthew G Knepley for (d = off; d < off+dof; ++d) { 241cb1e1211SMatthew G Knepley ierr = PetscSectionAddDof(leafSectionAdj, d, ndof-ncdof);CHKERRQ(ierr); 242cb1e1211SMatthew G Knepley } 243cb1e1211SMatthew G Knepley } 24476185916SToby Isaac ierr = PetscSectionGetDof(anchorSectionAdj, p, &anDof);CHKERRQ(ierr); 24576185916SToby Isaac if (anDof) { 24676185916SToby Isaac for (d = off; d < off+dof; ++d) { 24776185916SToby Isaac ierr = PetscSectionAddDof(leafSectionAdj, d, anDof);CHKERRQ(ierr); 24876185916SToby Isaac } 24976185916SToby Isaac } 250cb1e1211SMatthew G Knepley } 251cb1e1211SMatthew G Knepley ierr = PetscSectionSetUp(leafSectionAdj);CHKERRQ(ierr); 252cb1e1211SMatthew G Knepley if (debug) { 253cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Adjacency Section for Preallocation on Leaves:\n");CHKERRQ(ierr); 254cb1e1211SMatthew G Knepley ierr = PetscSectionView(leafSectionAdj, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 255cb1e1211SMatthew G Knepley } 256cb1e1211SMatthew G Knepley /* Get maximum remote adjacency sizes for owned dofs on interface (roots) */ 25747a6104aSMatthew G. Knepley if (doComm) { 258cb1e1211SMatthew G Knepley ierr = PetscSFReduceBegin(sfDof, MPIU_INT, leafSectionAdj->atlasDof, rootSectionAdj->atlasDof, MPI_SUM);CHKERRQ(ierr); 259cb1e1211SMatthew G Knepley ierr = PetscSFReduceEnd(sfDof, MPIU_INT, leafSectionAdj->atlasDof, rootSectionAdj->atlasDof, MPI_SUM);CHKERRQ(ierr); 260cb1e1211SMatthew G Knepley } 261cb1e1211SMatthew G Knepley if (debug) { 262cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Adjancency Section for Preallocation on Roots:\n");CHKERRQ(ierr); 263cb1e1211SMatthew G Knepley ierr = PetscSectionView(rootSectionAdj, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 264cb1e1211SMatthew G Knepley } 265cb1e1211SMatthew G Knepley /* Add in local adjacency sizes for owned dofs on interface (roots) */ 266cb1e1211SMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 26776185916SToby Isaac PetscInt numAdj = PETSC_DETERMINE, adof, dof, off, d, q, anDof; 268cb1e1211SMatthew G Knepley 269cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 270cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); 271cb1e1211SMatthew G Knepley if (!dof) continue; 272cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(rootSectionAdj, off, &adof);CHKERRQ(ierr); 273cb1e1211SMatthew G Knepley if (adof <= 0) continue; 274a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacency_Internal(dm, p, useCone, useClosure, useAnchors, &numAdj, &tmpAdj);CHKERRQ(ierr); 275cb1e1211SMatthew G Knepley for (q = 0; q < numAdj; ++q) { 276cb1e1211SMatthew G Knepley const PetscInt padj = tmpAdj[q]; 277cb1e1211SMatthew G Knepley PetscInt ndof, ncdof; 278cb1e1211SMatthew G Knepley 279cb1e1211SMatthew G Knepley if ((padj < pStart) || (padj >= pEnd)) continue; 280cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, padj, &ndof);CHKERRQ(ierr); 281cb1e1211SMatthew G Knepley ierr = PetscSectionGetConstraintDof(section, padj, &ncdof);CHKERRQ(ierr); 282cb1e1211SMatthew G Knepley for (d = off; d < off+dof; ++d) { 283cb1e1211SMatthew G Knepley ierr = PetscSectionAddDof(rootSectionAdj, d, ndof-ncdof);CHKERRQ(ierr); 284cb1e1211SMatthew G Knepley } 285cb1e1211SMatthew G Knepley } 28676185916SToby Isaac ierr = PetscSectionGetDof(anchorSectionAdj, p, &anDof);CHKERRQ(ierr); 28776185916SToby Isaac if (anDof) { 28876185916SToby Isaac for (d = off; d < off+dof; ++d) { 28976185916SToby Isaac ierr = PetscSectionAddDof(rootSectionAdj, d, anDof);CHKERRQ(ierr); 29076185916SToby Isaac } 29176185916SToby Isaac } 292cb1e1211SMatthew G Knepley } 293cb1e1211SMatthew G Knepley ierr = PetscSectionSetUp(rootSectionAdj);CHKERRQ(ierr); 294cb1e1211SMatthew G Knepley if (debug) { 295cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Adjancency Section for Preallocation on Roots after local additions:\n");CHKERRQ(ierr); 296cb1e1211SMatthew G Knepley ierr = PetscSectionView(rootSectionAdj, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 297cb1e1211SMatthew G Knepley } 298cb1e1211SMatthew G Knepley /* Create adj SF based on dof SF */ 299cb1e1211SMatthew G Knepley ierr = PetscSFCreateRemoteOffsets(sfDof, rootSectionAdj, leafSectionAdj, &remoteOffsets);CHKERRQ(ierr); 300cb1e1211SMatthew G Knepley ierr = PetscSFCreateSectionSF(sfDof, rootSectionAdj, remoteOffsets, leafSectionAdj, &sfAdj);CHKERRQ(ierr); 301cb1e1211SMatthew G Knepley if (debug) { 302cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Adjacency SF for Preallocation:\n");CHKERRQ(ierr); 303cb1e1211SMatthew G Knepley ierr = PetscSFView(sfAdj, NULL);CHKERRQ(ierr); 304cb1e1211SMatthew G Knepley } 305cb1e1211SMatthew G Knepley /* Create leaf adjacency */ 306cb1e1211SMatthew G Knepley ierr = PetscSectionSetUp(leafSectionAdj);CHKERRQ(ierr); 307cb1e1211SMatthew G Knepley ierr = PetscSectionGetStorageSize(leafSectionAdj, &adjSize);CHKERRQ(ierr); 3081795a4d1SJed Brown ierr = PetscCalloc1(adjSize, &adj);CHKERRQ(ierr); 309cb1e1211SMatthew G Knepley for (l = 0; l < nleaves; ++l) { 31076185916SToby Isaac PetscInt dof, off, d, q, anDof, anOff; 31170034214SMatthew G. Knepley PetscInt p = leaves[l], numAdj = PETSC_DETERMINE; 312cb1e1211SMatthew G Knepley 313fb47e2feSMatthew G. Knepley if ((p < pStart) || (p >= pEnd)) continue; 314cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 315cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); 316a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacency_Internal(dm, p, useCone, useClosure, useAnchors, &numAdj, &tmpAdj);CHKERRQ(ierr); 31776185916SToby Isaac ierr = PetscSectionGetDof(anchorSectionAdj, p, &anDof);CHKERRQ(ierr); 31876185916SToby Isaac ierr = PetscSectionGetOffset(anchorSectionAdj, p, &anOff);CHKERRQ(ierr); 319cb1e1211SMatthew G Knepley for (d = off; d < off+dof; ++d) { 320cb1e1211SMatthew G Knepley PetscInt aoff, i = 0; 321cb1e1211SMatthew G Knepley 322cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(leafSectionAdj, d, &aoff);CHKERRQ(ierr); 323cb1e1211SMatthew G Knepley for (q = 0; q < numAdj; ++q) { 324cb1e1211SMatthew G Knepley const PetscInt padj = tmpAdj[q]; 325cb1e1211SMatthew G Knepley PetscInt ndof, ncdof, ngoff, nd; 326cb1e1211SMatthew G Knepley 327cb1e1211SMatthew G Knepley if ((padj < pStart) || (padj >= pEnd)) continue; 328cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, padj, &ndof);CHKERRQ(ierr); 329cb1e1211SMatthew G Knepley ierr = PetscSectionGetConstraintDof(section, padj, &ncdof);CHKERRQ(ierr); 330cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, padj, &ngoff);CHKERRQ(ierr); 331cb1e1211SMatthew G Knepley for (nd = 0; nd < ndof-ncdof; ++nd) { 332cb1e1211SMatthew G Knepley adj[aoff+i] = (ngoff < 0 ? -(ngoff+1) : ngoff) + nd; 333cb1e1211SMatthew G Knepley ++i; 334cb1e1211SMatthew G Knepley } 335cb1e1211SMatthew G Knepley } 33676185916SToby Isaac for (q = 0; q < anDof; q++) { 33776185916SToby Isaac adj[aoff+i] = anchorAdj[anOff+q]; 33876185916SToby Isaac ++i; 33976185916SToby Isaac } 340cb1e1211SMatthew G Knepley } 341cb1e1211SMatthew G Knepley } 342cb1e1211SMatthew G Knepley /* Debugging */ 343cb1e1211SMatthew G Knepley if (debug) { 344cb1e1211SMatthew G Knepley IS tmp; 345cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Leaf adjacency indices\n");CHKERRQ(ierr); 346cb1e1211SMatthew G Knepley ierr = ISCreateGeneral(comm, adjSize, adj, PETSC_USE_POINTER, &tmp);CHKERRQ(ierr); 347cb1e1211SMatthew G Knepley ierr = ISView(tmp, NULL);CHKERRQ(ierr); 3480a7e1f69SMatthew G. Knepley ierr = ISDestroy(&tmp);CHKERRQ(ierr); 349cb1e1211SMatthew G Knepley } 350543482b8SMatthew G. Knepley /* Gather adjacent indices to root */ 351cb1e1211SMatthew G Knepley ierr = PetscSectionGetStorageSize(rootSectionAdj, &adjSize);CHKERRQ(ierr); 352785e854fSJed Brown ierr = PetscMalloc1(adjSize, &rootAdj);CHKERRQ(ierr); 353cb1e1211SMatthew G Knepley for (r = 0; r < adjSize; ++r) rootAdj[r] = -1; 35447a6104aSMatthew G. Knepley if (doComm) { 355543482b8SMatthew G. Knepley const PetscInt *indegree; 356543482b8SMatthew G. Knepley PetscInt *remoteadj, radjsize = 0; 357543482b8SMatthew G. Knepley 358543482b8SMatthew G. Knepley ierr = PetscSFComputeDegreeBegin(sfAdj, &indegree);CHKERRQ(ierr); 359543482b8SMatthew G. Knepley ierr = PetscSFComputeDegreeEnd(sfAdj, &indegree);CHKERRQ(ierr); 360543482b8SMatthew G. Knepley for (p = 0; p < adjSize; ++p) radjsize += indegree[p]; 361543482b8SMatthew G. Knepley ierr = PetscMalloc1(radjsize, &remoteadj);CHKERRQ(ierr); 362543482b8SMatthew G. Knepley ierr = PetscSFGatherBegin(sfAdj, MPIU_INT, adj, remoteadj);CHKERRQ(ierr); 363543482b8SMatthew G. Knepley ierr = PetscSFGatherEnd(sfAdj, MPIU_INT, adj, remoteadj);CHKERRQ(ierr); 3646dba2905SMatthew G. Knepley for (p = 0, l = 0, r = 0; p < adjSize; ++p, l = PetscMax(p, l + indegree[p-1])) { 365543482b8SMatthew G. Knepley PetscInt s; 3666dba2905SMatthew G. Knepley for (s = 0; s < indegree[p]; ++s, ++r) rootAdj[l+s] = remoteadj[r]; 367543482b8SMatthew G. Knepley } 368543482b8SMatthew G. Knepley if (r != radjsize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistency in communication %d != %d", r, radjsize); 3696dba2905SMatthew G. Knepley if (l != adjSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistency in communication %d != %d", l, adjSize); 370543482b8SMatthew G. Knepley ierr = PetscFree(remoteadj);CHKERRQ(ierr); 371cb1e1211SMatthew G Knepley } 372cb1e1211SMatthew G Knepley ierr = PetscSFDestroy(&sfAdj);CHKERRQ(ierr); 373cb1e1211SMatthew G Knepley ierr = PetscFree(adj);CHKERRQ(ierr); 374cb1e1211SMatthew G Knepley /* Debugging */ 375cb1e1211SMatthew G Knepley if (debug) { 376cb1e1211SMatthew G Knepley IS tmp; 377cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Root adjacency indices after gather\n");CHKERRQ(ierr); 378cb1e1211SMatthew G Knepley ierr = ISCreateGeneral(comm, adjSize, rootAdj, PETSC_USE_POINTER, &tmp);CHKERRQ(ierr); 379cb1e1211SMatthew G Knepley ierr = ISView(tmp, NULL);CHKERRQ(ierr); 3800a7e1f69SMatthew G. Knepley ierr = ISDestroy(&tmp);CHKERRQ(ierr); 381cb1e1211SMatthew G Knepley } 382cb1e1211SMatthew G Knepley /* Add in local adjacency indices for owned dofs on interface (roots) */ 383cb1e1211SMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 38476185916SToby Isaac PetscInt numAdj = PETSC_DETERMINE, adof, dof, off, d, q, anDof, anOff; 385cb1e1211SMatthew G Knepley 386cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 387cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); 388cb1e1211SMatthew G Knepley if (!dof) continue; 389cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(rootSectionAdj, off, &adof);CHKERRQ(ierr); 390cb1e1211SMatthew G Knepley if (adof <= 0) continue; 391a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacency_Internal(dm, p, useCone, useClosure, useAnchors, &numAdj, &tmpAdj);CHKERRQ(ierr); 39276185916SToby Isaac ierr = PetscSectionGetDof(anchorSectionAdj, p, &anDof);CHKERRQ(ierr); 39376185916SToby Isaac ierr = PetscSectionGetOffset(anchorSectionAdj, p, &anOff);CHKERRQ(ierr); 394cb1e1211SMatthew G Knepley for (d = off; d < off+dof; ++d) { 395cb1e1211SMatthew G Knepley PetscInt adof, aoff, i; 396cb1e1211SMatthew G Knepley 397cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(rootSectionAdj, d, &adof);CHKERRQ(ierr); 398cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(rootSectionAdj, d, &aoff);CHKERRQ(ierr); 399cb1e1211SMatthew G Knepley i = adof-1; 40076185916SToby Isaac for (q = 0; q < anDof; q++) { 40176185916SToby Isaac rootAdj[aoff+i] = anchorAdj[anOff+q]; 40276185916SToby Isaac --i; 40376185916SToby Isaac } 404cb1e1211SMatthew G Knepley for (q = 0; q < numAdj; ++q) { 405cb1e1211SMatthew G Knepley const PetscInt padj = tmpAdj[q]; 406cb1e1211SMatthew G Knepley PetscInt ndof, ncdof, ngoff, nd; 407cb1e1211SMatthew G Knepley 408cb1e1211SMatthew G Knepley if ((padj < pStart) || (padj >= pEnd)) continue; 409cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, padj, &ndof);CHKERRQ(ierr); 410cb1e1211SMatthew G Knepley ierr = PetscSectionGetConstraintDof(section, padj, &ncdof);CHKERRQ(ierr); 411cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, padj, &ngoff);CHKERRQ(ierr); 412cb1e1211SMatthew G Knepley for (nd = 0; nd < ndof-ncdof; ++nd) { 413cb1e1211SMatthew G Knepley rootAdj[aoff+i] = ngoff < 0 ? -(ngoff+1)+nd : ngoff+nd; 414cb1e1211SMatthew G Knepley --i; 415cb1e1211SMatthew G Knepley } 416cb1e1211SMatthew G Knepley } 417cb1e1211SMatthew G Knepley } 418cb1e1211SMatthew G Knepley } 419cb1e1211SMatthew G Knepley /* Debugging */ 420cb1e1211SMatthew G Knepley if (debug) { 421cb1e1211SMatthew G Knepley IS tmp; 422cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Root adjacency indices\n");CHKERRQ(ierr); 423cb1e1211SMatthew G Knepley ierr = ISCreateGeneral(comm, adjSize, rootAdj, PETSC_USE_POINTER, &tmp);CHKERRQ(ierr); 424cb1e1211SMatthew G Knepley ierr = ISView(tmp, NULL);CHKERRQ(ierr); 4250a7e1f69SMatthew G. Knepley ierr = ISDestroy(&tmp);CHKERRQ(ierr); 426cb1e1211SMatthew G Knepley } 427cb1e1211SMatthew G Knepley /* Compress indices */ 428cb1e1211SMatthew G Knepley ierr = PetscSectionSetUp(rootSectionAdj);CHKERRQ(ierr); 429cb1e1211SMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 430cb1e1211SMatthew G Knepley PetscInt dof, cdof, off, d; 431cb1e1211SMatthew G Knepley PetscInt adof, aoff; 432cb1e1211SMatthew G Knepley 433cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 434cb1e1211SMatthew G Knepley ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 435cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); 436cb1e1211SMatthew G Knepley if (!dof) continue; 437cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(rootSectionAdj, off, &adof);CHKERRQ(ierr); 438cb1e1211SMatthew G Knepley if (adof <= 0) continue; 439cb1e1211SMatthew G Knepley for (d = off; d < off+dof-cdof; ++d) { 440cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(rootSectionAdj, d, &adof);CHKERRQ(ierr); 441cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(rootSectionAdj, d, &aoff);CHKERRQ(ierr); 442cb1e1211SMatthew G Knepley ierr = PetscSortRemoveDupsInt(&adof, &rootAdj[aoff]);CHKERRQ(ierr); 443cb1e1211SMatthew G Knepley ierr = PetscSectionSetDof(rootSectionAdj, d, adof);CHKERRQ(ierr); 444cb1e1211SMatthew G Knepley } 445cb1e1211SMatthew G Knepley } 446cb1e1211SMatthew G Knepley /* Debugging */ 447cb1e1211SMatthew G Knepley if (debug) { 448cb1e1211SMatthew G Knepley IS tmp; 449cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Adjancency Section for Preallocation on Roots after compression:\n");CHKERRQ(ierr); 450cb1e1211SMatthew G Knepley ierr = PetscSectionView(rootSectionAdj, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 451cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Root adjacency indices after compression\n");CHKERRQ(ierr); 452cb1e1211SMatthew G Knepley ierr = ISCreateGeneral(comm, adjSize, rootAdj, PETSC_USE_POINTER, &tmp);CHKERRQ(ierr); 453cb1e1211SMatthew G Knepley ierr = ISView(tmp, NULL);CHKERRQ(ierr); 4540a7e1f69SMatthew G. Knepley ierr = ISDestroy(&tmp);CHKERRQ(ierr); 455cb1e1211SMatthew G Knepley } 456cb1e1211SMatthew G Knepley /* Build adjacency section: Maps global indices to sets of adjacent global indices */ 457cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffsetRange(sectionGlobal, &globalOffStart, &globalOffEnd);CHKERRQ(ierr); 458cb1e1211SMatthew G Knepley ierr = PetscSectionCreate(comm, §ionAdj);CHKERRQ(ierr); 459cb1e1211SMatthew G Knepley ierr = PetscSectionSetChart(sectionAdj, globalOffStart, globalOffEnd);CHKERRQ(ierr); 460cb1e1211SMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 46176185916SToby Isaac PetscInt numAdj = PETSC_DETERMINE, dof, cdof, off, goff, d, q, anDof; 462cb1e1211SMatthew G Knepley PetscBool found = PETSC_TRUE; 463cb1e1211SMatthew G Knepley 464cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 465cb1e1211SMatthew G Knepley ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 466cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); 467cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); 468cb1e1211SMatthew G Knepley for (d = 0; d < dof-cdof; ++d) { 469cb1e1211SMatthew G Knepley PetscInt ldof, rdof; 470cb1e1211SMatthew G Knepley 471cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(leafSectionAdj, off+d, &ldof);CHKERRQ(ierr); 472cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(rootSectionAdj, off+d, &rdof);CHKERRQ(ierr); 473cb1e1211SMatthew G Knepley if (ldof > 0) { 474cb1e1211SMatthew G Knepley /* We do not own this point */ 475cb1e1211SMatthew G Knepley } else if (rdof > 0) { 476cb1e1211SMatthew G Knepley ierr = PetscSectionSetDof(sectionAdj, goff+d, rdof);CHKERRQ(ierr); 477cb1e1211SMatthew G Knepley } else { 478cb1e1211SMatthew G Knepley found = PETSC_FALSE; 479cb1e1211SMatthew G Knepley } 480cb1e1211SMatthew G Knepley } 481cb1e1211SMatthew G Knepley if (found) continue; 482cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 483cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); 484a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacency_Internal(dm, p, useCone, useClosure, useAnchors, &numAdj, &tmpAdj);CHKERRQ(ierr); 485cb1e1211SMatthew G Knepley for (q = 0; q < numAdj; ++q) { 486cb1e1211SMatthew G Knepley const PetscInt padj = tmpAdj[q]; 487cb1e1211SMatthew G Knepley PetscInt ndof, ncdof, noff; 488cb1e1211SMatthew G Knepley 489cb1e1211SMatthew G Knepley if ((padj < pStart) || (padj >= pEnd)) continue; 490cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, padj, &ndof);CHKERRQ(ierr); 491cb1e1211SMatthew G Knepley ierr = PetscSectionGetConstraintDof(section, padj, &ncdof);CHKERRQ(ierr); 492cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(section, padj, &noff);CHKERRQ(ierr); 493cb1e1211SMatthew G Knepley for (d = goff; d < goff+dof-cdof; ++d) { 494cb1e1211SMatthew G Knepley ierr = PetscSectionAddDof(sectionAdj, d, ndof-ncdof);CHKERRQ(ierr); 495cb1e1211SMatthew G Knepley } 496cb1e1211SMatthew G Knepley } 49776185916SToby Isaac ierr = PetscSectionGetDof(anchorSectionAdj, p, &anDof);CHKERRQ(ierr); 49876185916SToby Isaac if (anDof) { 49976185916SToby Isaac for (d = goff; d < goff+dof-cdof; ++d) { 50076185916SToby Isaac ierr = PetscSectionAddDof(sectionAdj, d, anDof);CHKERRQ(ierr); 50176185916SToby Isaac } 50276185916SToby Isaac } 503cb1e1211SMatthew G Knepley } 504cb1e1211SMatthew G Knepley ierr = PetscSectionSetUp(sectionAdj);CHKERRQ(ierr); 505cb1e1211SMatthew G Knepley if (debug) { 506cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Adjacency Section for Preallocation:\n");CHKERRQ(ierr); 507cb1e1211SMatthew G Knepley ierr = PetscSectionView(sectionAdj, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 508cb1e1211SMatthew G Knepley } 509cb1e1211SMatthew G Knepley /* Get adjacent indices */ 510cb1e1211SMatthew G Knepley ierr = PetscSectionGetStorageSize(sectionAdj, &numCols);CHKERRQ(ierr); 511785e854fSJed Brown ierr = PetscMalloc1(numCols, &cols);CHKERRQ(ierr); 512cb1e1211SMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 51376185916SToby Isaac PetscInt numAdj = PETSC_DETERMINE, dof, cdof, off, goff, d, q, anDof, anOff; 514cb1e1211SMatthew G Knepley PetscBool found = PETSC_TRUE; 515cb1e1211SMatthew G Knepley 516cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 517cb1e1211SMatthew G Knepley ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 518cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); 519cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); 520cb1e1211SMatthew G Knepley for (d = 0; d < dof-cdof; ++d) { 521cb1e1211SMatthew G Knepley PetscInt ldof, rdof; 522cb1e1211SMatthew G Knepley 523cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(leafSectionAdj, off+d, &ldof);CHKERRQ(ierr); 524cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(rootSectionAdj, off+d, &rdof);CHKERRQ(ierr); 525cb1e1211SMatthew G Knepley if (ldof > 0) { 526cb1e1211SMatthew G Knepley /* We do not own this point */ 527cb1e1211SMatthew G Knepley } else if (rdof > 0) { 528cb1e1211SMatthew G Knepley PetscInt aoff, roff; 529cb1e1211SMatthew G Knepley 530cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(sectionAdj, goff+d, &aoff);CHKERRQ(ierr); 531cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(rootSectionAdj, off+d, &roff);CHKERRQ(ierr); 532cb1e1211SMatthew G Knepley ierr = PetscMemcpy(&cols[aoff], &rootAdj[roff], rdof * sizeof(PetscInt));CHKERRQ(ierr); 533cb1e1211SMatthew G Knepley } else { 534cb1e1211SMatthew G Knepley found = PETSC_FALSE; 535cb1e1211SMatthew G Knepley } 536cb1e1211SMatthew G Knepley } 537cb1e1211SMatthew G Knepley if (found) continue; 538a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacency_Internal(dm, p, useCone, useClosure, useAnchors, &numAdj, &tmpAdj);CHKERRQ(ierr); 53976185916SToby Isaac ierr = PetscSectionGetDof(anchorSectionAdj, p, &anDof);CHKERRQ(ierr); 54076185916SToby Isaac ierr = PetscSectionGetOffset(anchorSectionAdj, p, &anOff);CHKERRQ(ierr); 541cb1e1211SMatthew G Knepley for (d = goff; d < goff+dof-cdof; ++d) { 542cb1e1211SMatthew G Knepley PetscInt adof, aoff, i = 0; 543cb1e1211SMatthew G Knepley 544cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(sectionAdj, d, &adof);CHKERRQ(ierr); 545cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(sectionAdj, d, &aoff);CHKERRQ(ierr); 546cb1e1211SMatthew G Knepley for (q = 0; q < numAdj; ++q) { 547cb1e1211SMatthew G Knepley const PetscInt padj = tmpAdj[q]; 548cb1e1211SMatthew G Knepley PetscInt ndof, ncdof, ngoff, nd; 549cb1e1211SMatthew G Knepley const PetscInt *ncind; 550cb1e1211SMatthew G Knepley 551cb1e1211SMatthew G Knepley /* Adjacent points may not be in the section chart */ 552cb1e1211SMatthew G Knepley if ((padj < pStart) || (padj >= pEnd)) continue; 553cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(section, padj, &ndof);CHKERRQ(ierr); 554cb1e1211SMatthew G Knepley ierr = PetscSectionGetConstraintDof(section, padj, &ncdof);CHKERRQ(ierr); 555cb1e1211SMatthew G Knepley ierr = PetscSectionGetConstraintIndices(section, padj, &ncind);CHKERRQ(ierr); 556cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, padj, &ngoff);CHKERRQ(ierr); 557cb1e1211SMatthew G Knepley for (nd = 0; nd < ndof-ncdof; ++nd, ++i) { 558cb1e1211SMatthew G Knepley cols[aoff+i] = ngoff < 0 ? -(ngoff+1)+nd : ngoff+nd; 559cb1e1211SMatthew G Knepley } 560cb1e1211SMatthew G Knepley } 56176185916SToby Isaac for (q = 0; q < anDof; q++, i++) { 56276185916SToby Isaac cols[aoff+i] = anchorAdj[anOff + q]; 56376185916SToby Isaac } 564cb1e1211SMatthew G Knepley if (i != adof) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid number of entries %D != %D for dof %D (point %D)", i, adof, d, p); 565cb1e1211SMatthew G Knepley } 566cb1e1211SMatthew G Knepley } 56776185916SToby Isaac ierr = PetscSectionDestroy(&anchorSectionAdj);CHKERRQ(ierr); 568cb1e1211SMatthew G Knepley ierr = PetscSectionDestroy(&leafSectionAdj);CHKERRQ(ierr); 569cb1e1211SMatthew G Knepley ierr = PetscSectionDestroy(&rootSectionAdj);CHKERRQ(ierr); 57076185916SToby Isaac ierr = PetscFree(anchorAdj);CHKERRQ(ierr); 571cb1e1211SMatthew G Knepley ierr = PetscFree(rootAdj);CHKERRQ(ierr); 57270034214SMatthew G. Knepley ierr = PetscFree(tmpAdj);CHKERRQ(ierr); 573cb1e1211SMatthew G Knepley /* Debugging */ 574cb1e1211SMatthew G Knepley if (debug) { 575cb1e1211SMatthew G Knepley IS tmp; 576cb1e1211SMatthew G Knepley ierr = PetscPrintf(comm, "Column indices\n");CHKERRQ(ierr); 577cb1e1211SMatthew G Knepley ierr = ISCreateGeneral(comm, numCols, cols, PETSC_USE_POINTER, &tmp);CHKERRQ(ierr); 578cb1e1211SMatthew G Knepley ierr = ISView(tmp, NULL);CHKERRQ(ierr); 5790a7e1f69SMatthew G. Knepley ierr = ISDestroy(&tmp);CHKERRQ(ierr); 580cb1e1211SMatthew G Knepley } 581a9fb6443SMatthew G. Knepley 582a9fb6443SMatthew G. Knepley *sA = sectionAdj; 583a9fb6443SMatthew G. Knepley *colIdx = cols; 584a9fb6443SMatthew G. Knepley PetscFunctionReturn(0); 585a9fb6443SMatthew G. Knepley } 586a9fb6443SMatthew G. Knepley 587a9fb6443SMatthew G. Knepley #undef __FUNCT__ 588a9fb6443SMatthew G. Knepley #define __FUNCT__ "DMPlexUpdateAllocation_Static" 589e101f074SMatthew G. Knepley PetscErrorCode DMPlexUpdateAllocation_Static(DM dm, PetscLayout rLayout, PetscInt bs, PetscInt f, PetscSection sectionAdj, const PetscInt cols[], PetscInt dnz[], PetscInt onz[], PetscInt dnzu[], PetscInt onzu[]) 590a9fb6443SMatthew G. Knepley { 591e101f074SMatthew G. Knepley PetscSection section; 592a9fb6443SMatthew G. Knepley PetscInt rStart, rEnd, r, pStart, pEnd, p; 593a9fb6443SMatthew G. Knepley PetscErrorCode ierr; 594a9fb6443SMatthew G. Knepley 595a9fb6443SMatthew G. Knepley PetscFunctionBegin; 596a9fb6443SMatthew G. Knepley /* This loop needs to change to a loop over points, then field dofs, which means we need to look both sections */ 597cb1e1211SMatthew G Knepley ierr = PetscLayoutGetRange(rLayout, &rStart, &rEnd);CHKERRQ(ierr); 598a9fb6443SMatthew G. Knepley if (rStart%bs || rEnd%bs) SETERRQ3(PetscObjectComm((PetscObject) rLayout), PETSC_ERR_ARG_WRONG, "Invalid layout [%d, %d) for matrix, must be divisible by block size %d", rStart, rEnd, bs); 599a9fb6443SMatthew G. Knepley if (f >= 0 && bs == 1) { 600e101f074SMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 601a9fb6443SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 602a9fb6443SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 603294b7009SMatthew G. Knepley PetscInt rS, rE; 604a9fb6443SMatthew G. Knepley 605294b7009SMatthew G. Knepley ierr = DMPlexGetGlobalFieldOffset_Private(dm, p, f, &rS, &rE);CHKERRQ(ierr); 606a9fb6443SMatthew G. Knepley for (r = rS; r < rE; ++r) { 607a9fb6443SMatthew G. Knepley PetscInt numCols, cStart, c; 608a9fb6443SMatthew G. Knepley 609a9fb6443SMatthew G. Knepley ierr = PetscSectionGetDof(sectionAdj, r, &numCols);CHKERRQ(ierr); 610a9fb6443SMatthew G. Knepley ierr = PetscSectionGetOffset(sectionAdj, r, &cStart);CHKERRQ(ierr); 611a9fb6443SMatthew G. Knepley for (c = cStart; c < cStart+numCols; ++c) { 612a9fb6443SMatthew G. Knepley if ((cols[c] >= rStart) && (cols[c] < rEnd)) { 613a9fb6443SMatthew G. Knepley ++dnz[r-rStart]; 614a9fb6443SMatthew G. Knepley if (cols[c] >= r) ++dnzu[r-rStart]; 615a9fb6443SMatthew G. Knepley } else { 616a9fb6443SMatthew G. Knepley ++onz[r-rStart]; 617a9fb6443SMatthew G. Knepley if (cols[c] >= r) ++onzu[r-rStart]; 618a9fb6443SMatthew G. Knepley } 619a9fb6443SMatthew G. Knepley } 620a9fb6443SMatthew G. Knepley } 621a9fb6443SMatthew G. Knepley } 622a9fb6443SMatthew G. Knepley } else { 623cb1e1211SMatthew G Knepley /* Only loop over blocks of rows */ 624cb1e1211SMatthew G Knepley for (r = rStart/bs; r < rEnd/bs; ++r) { 625cb1e1211SMatthew G Knepley const PetscInt row = r*bs; 626cb1e1211SMatthew G Knepley PetscInt numCols, cStart, c; 627cb1e1211SMatthew G Knepley 628cb1e1211SMatthew G Knepley ierr = PetscSectionGetDof(sectionAdj, row, &numCols);CHKERRQ(ierr); 629cb1e1211SMatthew G Knepley ierr = PetscSectionGetOffset(sectionAdj, row, &cStart);CHKERRQ(ierr); 630cb1e1211SMatthew G Knepley for (c = cStart; c < cStart+numCols; ++c) { 631cb1e1211SMatthew G Knepley if ((cols[c] >= rStart*bs) && (cols[c] < rEnd*bs)) { 632cb1e1211SMatthew G Knepley ++dnz[r-rStart]; 633cb1e1211SMatthew G Knepley if (cols[c] >= row) ++dnzu[r-rStart]; 634cb1e1211SMatthew G Knepley } else { 635cb1e1211SMatthew G Knepley ++onz[r-rStart]; 636cb1e1211SMatthew G Knepley if (cols[c] >= row) ++onzu[r-rStart]; 637cb1e1211SMatthew G Knepley } 638cb1e1211SMatthew G Knepley } 639cb1e1211SMatthew G Knepley } 640a9fb6443SMatthew G. Knepley for (r = 0; r < (rEnd - rStart)/bs; ++r) { 641cb1e1211SMatthew G Knepley dnz[r] /= bs; 642cb1e1211SMatthew G Knepley onz[r] /= bs; 643cb1e1211SMatthew G Knepley dnzu[r] /= bs; 644cb1e1211SMatthew G Knepley onzu[r] /= bs; 645cb1e1211SMatthew G Knepley } 646cb1e1211SMatthew G Knepley } 647a9fb6443SMatthew G. Knepley PetscFunctionReturn(0); 648a9fb6443SMatthew G. Knepley } 649a9fb6443SMatthew G. Knepley 650a9fb6443SMatthew G. Knepley #undef __FUNCT__ 651a9fb6443SMatthew G. Knepley #define __FUNCT__ "DMPlexFillMatrix_Static" 652e101f074SMatthew G. Knepley PetscErrorCode DMPlexFillMatrix_Static(DM dm, PetscLayout rLayout, PetscInt bs, PetscInt f, PetscSection sectionAdj, const PetscInt cols[], Mat A) 653a9fb6443SMatthew G. Knepley { 654e101f074SMatthew G. Knepley PetscSection section; 655a9fb6443SMatthew G. Knepley PetscScalar *values; 656a9fb6443SMatthew G. Knepley PetscInt rStart, rEnd, r, pStart, pEnd, p, len, maxRowLen = 0; 657a9fb6443SMatthew G. Knepley PetscErrorCode ierr; 658a9fb6443SMatthew G. Knepley 659a9fb6443SMatthew G. Knepley PetscFunctionBegin; 660a9fb6443SMatthew G. Knepley ierr = PetscLayoutGetRange(rLayout, &rStart, &rEnd);CHKERRQ(ierr); 661a9fb6443SMatthew G. Knepley for (r = rStart; r < rEnd; ++r) { 662a9fb6443SMatthew G. Knepley ierr = PetscSectionGetDof(sectionAdj, r, &len);CHKERRQ(ierr); 663a9fb6443SMatthew G. Knepley maxRowLen = PetscMax(maxRowLen, len); 664a9fb6443SMatthew G. Knepley } 665a9fb6443SMatthew G. Knepley ierr = PetscCalloc1(maxRowLen, &values);CHKERRQ(ierr); 666a9fb6443SMatthew G. Knepley if (f >=0 && bs == 1) { 667e101f074SMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 668a9fb6443SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 669a9fb6443SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 670294b7009SMatthew G. Knepley PetscInt rS, rE; 671a9fb6443SMatthew G. Knepley 672294b7009SMatthew G. Knepley ierr = DMPlexGetGlobalFieldOffset_Private(dm, p, f, &rS, &rE);CHKERRQ(ierr); 673a9fb6443SMatthew G. Knepley for (r = rS; r < rE; ++r) { 6747e01ee02SMatthew G. Knepley PetscInt numCols, cStart; 675a9fb6443SMatthew G. Knepley 676a9fb6443SMatthew G. Knepley ierr = PetscSectionGetDof(sectionAdj, r, &numCols);CHKERRQ(ierr); 677a9fb6443SMatthew G. Knepley ierr = PetscSectionGetOffset(sectionAdj, r, &cStart);CHKERRQ(ierr); 678a9fb6443SMatthew G. Knepley ierr = MatSetValues(A, 1, &r, numCols, &cols[cStart], values, INSERT_VALUES);CHKERRQ(ierr); 679a9fb6443SMatthew G. Knepley } 680a9fb6443SMatthew G. Knepley } 681a9fb6443SMatthew G. Knepley } else { 682a9fb6443SMatthew G. Knepley for (r = rStart; r < rEnd; ++r) { 683a9fb6443SMatthew G. Knepley PetscInt numCols, cStart; 684a9fb6443SMatthew G. Knepley 685a9fb6443SMatthew G. Knepley ierr = PetscSectionGetDof(sectionAdj, r, &numCols);CHKERRQ(ierr); 686a9fb6443SMatthew G. Knepley ierr = PetscSectionGetOffset(sectionAdj, r, &cStart);CHKERRQ(ierr); 687a9fb6443SMatthew G. Knepley ierr = MatSetValues(A, 1, &r, numCols, &cols[cStart], values, INSERT_VALUES);CHKERRQ(ierr); 688a9fb6443SMatthew G. Knepley } 689a9fb6443SMatthew G. Knepley } 690a9fb6443SMatthew G. Knepley ierr = PetscFree(values);CHKERRQ(ierr); 691a9fb6443SMatthew G. Knepley PetscFunctionReturn(0); 692a9fb6443SMatthew G. Knepley } 693a9fb6443SMatthew G. Knepley 694a9fb6443SMatthew G. Knepley #undef __FUNCT__ 695a9fb6443SMatthew G. Knepley #define __FUNCT__ "DMPlexPreallocateOperator" 696e101f074SMatthew G. Knepley PetscErrorCode DMPlexPreallocateOperator(DM dm, PetscInt bs, PetscInt dnz[], PetscInt onz[], PetscInt dnzu[], PetscInt onzu[], Mat A, PetscBool fillMatrix) 697a9fb6443SMatthew G. Knepley { 698a9fb6443SMatthew G. Knepley MPI_Comm comm; 699a9fb6443SMatthew G. Knepley PetscDS prob; 700a9fb6443SMatthew G. Knepley MatType mtype; 701a9fb6443SMatthew G. Knepley PetscSF sf, sfDof; 702e101f074SMatthew G. Knepley PetscSection section; 703a9fb6443SMatthew G. Knepley PetscInt *remoteOffsets; 704a9fb6443SMatthew G. Knepley PetscSection sectionAdj[4] = {NULL, NULL, NULL, NULL}; 705a9fb6443SMatthew G. Knepley PetscInt *cols[4] = {NULL, NULL, NULL, NULL}; 706a9fb6443SMatthew G. Knepley PetscBool useCone, useClosure; 7077e01ee02SMatthew G. Knepley PetscInt Nf, f, idx, locRows; 708a9fb6443SMatthew G. Knepley PetscLayout rLayout; 709a9fb6443SMatthew G. Knepley PetscBool isSymBlock, isSymSeqBlock, isSymMPIBlock, debug = PETSC_FALSE; 710a9fb6443SMatthew G. Knepley PetscErrorCode ierr; 711a9fb6443SMatthew G. Knepley 712a9fb6443SMatthew G. Knepley PetscFunctionBegin; 713a9fb6443SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 714a9fb6443SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 9); 715a9fb6443SMatthew G. Knepley if (dnz) PetscValidPointer(dnz,5); if (onz) PetscValidPointer(onz,6); 716a9fb6443SMatthew G. Knepley if (dnzu) PetscValidPointer(dnzu,7); if (onzu) PetscValidPointer(onzu,8); 717a9fb6443SMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 718a9fb6443SMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 719e101f074SMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 720a9fb6443SMatthew G. Knepley ierr = PetscOptionsGetBool(NULL, "-dm_view_preallocation", &debug, NULL);CHKERRQ(ierr); 721a9fb6443SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 722a9fb6443SMatthew G. Knepley ierr = PetscLogEventBegin(DMPLEX_Preallocate,dm,0,0,0);CHKERRQ(ierr); 723a9fb6443SMatthew G. Knepley /* Create dof SF based on point SF */ 724a9fb6443SMatthew G. Knepley if (debug) { 725e101f074SMatthew G. Knepley PetscSection section, sectionGlobal; 726a9fb6443SMatthew G. Knepley PetscSF sf; 727a9fb6443SMatthew G. Knepley 728a9fb6443SMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 729e101f074SMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 730e101f074SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 731a9fb6443SMatthew G. Knepley ierr = PetscPrintf(comm, "Input Section for Preallocation:\n");CHKERRQ(ierr); 732a9fb6443SMatthew G. Knepley ierr = PetscSectionView(section, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 733a9fb6443SMatthew G. Knepley ierr = PetscPrintf(comm, "Input Global Section for Preallocation:\n");CHKERRQ(ierr); 734a9fb6443SMatthew G. Knepley ierr = PetscSectionView(sectionGlobal, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 735a9fb6443SMatthew G. Knepley ierr = PetscPrintf(comm, "Input SF for Preallocation:\n");CHKERRQ(ierr); 736a9fb6443SMatthew G. Knepley ierr = PetscSFView(sf, NULL);CHKERRQ(ierr); 737a9fb6443SMatthew G. Knepley } 738a9fb6443SMatthew G. Knepley ierr = PetscSFCreateRemoteOffsets(sf, section, section, &remoteOffsets);CHKERRQ(ierr); 739a9fb6443SMatthew G. Knepley ierr = PetscSFCreateSectionSF(sf, section, remoteOffsets, section, &sfDof);CHKERRQ(ierr); 740a9fb6443SMatthew G. Knepley if (debug) { 741a9fb6443SMatthew G. Knepley ierr = PetscPrintf(comm, "Dof SF for Preallocation:\n");CHKERRQ(ierr); 742a9fb6443SMatthew G. Knepley ierr = PetscSFView(sfDof, NULL);CHKERRQ(ierr); 743a9fb6443SMatthew G. Knepley } 744a9fb6443SMatthew G. Knepley /* Create allocation vectors from adjacency graph */ 745a9fb6443SMatthew G. Knepley ierr = MatGetLocalSize(A, &locRows, NULL);CHKERRQ(ierr); 746a9fb6443SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &rLayout);CHKERRQ(ierr); 747a9fb6443SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(rLayout, locRows);CHKERRQ(ierr); 748a9fb6443SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(rLayout, 1);CHKERRQ(ierr); 749a9fb6443SMatthew G. Knepley ierr = PetscLayoutSetUp(rLayout);CHKERRQ(ierr); 750a9fb6443SMatthew G. Knepley /* There are 4 types of adjacency */ 751a9fb6443SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 752a9fb6443SMatthew G. Knepley if (Nf < 1 || bs > 1) { 753a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacencyUseCone(dm, &useCone);CHKERRQ(ierr); 754a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacencyUseClosure(dm, &useClosure);CHKERRQ(ierr); 755a9fb6443SMatthew G. Knepley idx = (useCone ? 1 : 0) + (useClosure ? 2 : 0); 756e101f074SMatthew G. Knepley ierr = DMPlexCreateAdjacencySection_Static(dm, bs, sfDof, useCone, useClosure, PETSC_TRUE, §ionAdj[idx], &cols[idx]);CHKERRQ(ierr); 757e101f074SMatthew G. Knepley ierr = DMPlexUpdateAllocation_Static(dm, rLayout, bs, -1, sectionAdj[idx], cols[idx], dnz, onz, dnzu, onzu);CHKERRQ(ierr); 758a9fb6443SMatthew G. Knepley } else { 759a9fb6443SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 760a9fb6443SMatthew G. Knepley ierr = PetscDSGetAdjacency(prob, f, &useCone, &useClosure);CHKERRQ(ierr); 761a9fb6443SMatthew G. Knepley idx = (useCone ? 1 : 0) + (useClosure ? 2 : 0); 762e101f074SMatthew G. Knepley if (!sectionAdj[idx]) {ierr = DMPlexCreateAdjacencySection_Static(dm, bs, sfDof, useCone, useClosure, PETSC_TRUE, §ionAdj[idx], &cols[idx]);CHKERRQ(ierr);} 763e101f074SMatthew G. Knepley ierr = DMPlexUpdateAllocation_Static(dm, rLayout, bs, f, sectionAdj[idx], cols[idx], dnz, onz, dnzu, onzu);CHKERRQ(ierr); 764a9fb6443SMatthew G. Knepley } 765a9fb6443SMatthew G. Knepley } 766a9fb6443SMatthew G. Knepley ierr = PetscSFDestroy(&sfDof);CHKERRQ(ierr); 767cb1e1211SMatthew G Knepley /* Set matrix pattern */ 768cb1e1211SMatthew G Knepley ierr = MatXAIJSetPreallocation(A, bs, dnz, onz, dnzu, onzu);CHKERRQ(ierr); 769cb1e1211SMatthew G Knepley ierr = MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 77089545effSMatthew G. Knepley /* Check for symmetric storage */ 77189545effSMatthew G. Knepley ierr = MatGetType(A, &mtype);CHKERRQ(ierr); 77289545effSMatthew G. Knepley ierr = PetscStrcmp(mtype, MATSBAIJ, &isSymBlock);CHKERRQ(ierr); 77389545effSMatthew G. Knepley ierr = PetscStrcmp(mtype, MATSEQSBAIJ, &isSymSeqBlock);CHKERRQ(ierr); 77489545effSMatthew G. Knepley ierr = PetscStrcmp(mtype, MATMPISBAIJ, &isSymMPIBlock);CHKERRQ(ierr); 77589545effSMatthew G. Knepley if (isSymBlock || isSymSeqBlock || isSymMPIBlock) {ierr = MatSetOption(A, MAT_IGNORE_LOWER_TRIANGULAR, PETSC_TRUE);CHKERRQ(ierr);} 776cb1e1211SMatthew G Knepley /* Fill matrix with zeros */ 777cb1e1211SMatthew G Knepley if (fillMatrix) { 778a9fb6443SMatthew G. Knepley if (Nf < 1 || bs > 1) { 779a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacencyUseCone(dm, &useCone);CHKERRQ(ierr); 780a9fb6443SMatthew G. Knepley ierr = DMPlexGetAdjacencyUseClosure(dm, &useClosure);CHKERRQ(ierr); 781a9fb6443SMatthew G. Knepley idx = (useCone ? 1 : 0) + (useClosure ? 2 : 0); 782e101f074SMatthew G. Knepley ierr = DMPlexFillMatrix_Static(dm, rLayout, bs, -1, sectionAdj[idx], cols[idx], A);CHKERRQ(ierr); 783a9fb6443SMatthew G. Knepley } else { 784a9fb6443SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 785a9fb6443SMatthew G. Knepley ierr = PetscDSGetAdjacency(prob, f, &useCone, &useClosure);CHKERRQ(ierr); 786a9fb6443SMatthew G. Knepley idx = (useCone ? 1 : 0) + (useClosure ? 2 : 0); 787e101f074SMatthew G. Knepley ierr = DMPlexFillMatrix_Static(dm, rLayout, bs, f, sectionAdj[idx], cols[idx], A);CHKERRQ(ierr); 788cb1e1211SMatthew G Knepley } 789cb1e1211SMatthew G Knepley } 790cb1e1211SMatthew G Knepley ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 791cb1e1211SMatthew G Knepley ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 792cb1e1211SMatthew G Knepley } 793a9fb6443SMatthew G. Knepley ierr = PetscLayoutDestroy(&rLayout);CHKERRQ(ierr); 794a9fb6443SMatthew G. Knepley for (idx = 0; idx < 4; ++idx) {ierr = PetscSectionDestroy(§ionAdj[idx]);CHKERRQ(ierr); ierr = PetscFree(cols[idx]);CHKERRQ(ierr);} 795a72f3261SMatthew G. Knepley ierr = PetscLogEventEnd(DMPLEX_Preallocate,dm,0,0,0);CHKERRQ(ierr); 796cb1e1211SMatthew G Knepley PetscFunctionReturn(0); 797cb1e1211SMatthew G Knepley } 798cb1e1211SMatthew G Knepley 799cb1e1211SMatthew G Knepley #if 0 800cb1e1211SMatthew G Knepley #undef __FUNCT__ 801cb1e1211SMatthew G Knepley #define __FUNCT__ "DMPlexPreallocateOperator_2" 802cb1e1211SMatthew G Knepley PetscErrorCode DMPlexPreallocateOperator_2(DM dm, PetscInt bs, PetscSection section, PetscSection sectionGlobal, PetscInt dnz[], PetscInt onz[], PetscInt dnzu[], PetscInt onzu[], Mat A, PetscBool fillMatrix) 803cb1e1211SMatthew G Knepley { 804cb1e1211SMatthew G Knepley PetscInt *tmpClosure,*tmpAdj,*visits; 805cb1e1211SMatthew G Knepley PetscInt c,cStart,cEnd,pStart,pEnd; 806cb1e1211SMatthew G Knepley PetscErrorCode ierr; 807cb1e1211SMatthew G Knepley 808cb1e1211SMatthew G Knepley PetscFunctionBegin; 809c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 810cb1e1211SMatthew G Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 811cb1e1211SMatthew G Knepley ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 812cb1e1211SMatthew G Knepley 813e7b80042SMatthew G. Knepley maxClosureSize = 2*PetscMax(PetscPowInt(mesh->maxConeSize,depth+1),PetscPowInt(mesh->maxSupportSize,depth+1)); 814cb1e1211SMatthew G Knepley 815cb1e1211SMatthew G Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 816cb1e1211SMatthew G Knepley npoints = pEnd - pStart; 817cb1e1211SMatthew G Knepley 818dcca6d9dSJed Brown ierr = PetscMalloc3(maxClosureSize,&tmpClosure,npoints,&lvisits,npoints,&visits);CHKERRQ(ierr); 819cb1e1211SMatthew G Knepley ierr = PetscMemzero(lvisits,(pEnd-pStart)*sizeof(PetscInt));CHKERRQ(ierr); 820cb1e1211SMatthew G Knepley ierr = PetscMemzero(visits,(pEnd-pStart)*sizeof(PetscInt));CHKERRQ(ierr); 821cb1e1211SMatthew G Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 822cb1e1211SMatthew G Knepley for (c=cStart; c<cEnd; c++) { 823cb1e1211SMatthew G Knepley PetscInt *support = tmpClosure; 824cb1e1211SMatthew G Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_FALSE, &supportSize, (PetscInt**)&support);CHKERRQ(ierr); 825cb1e1211SMatthew G Knepley for (p=0; p<supportSize; p++) lvisits[support[p]]++; 826cb1e1211SMatthew G Knepley } 827cb1e1211SMatthew G Knepley ierr = PetscSFReduceBegin(sf,MPIU_INT,lvisits,visits,MPI_SUM);CHKERRQ(ierr); 828cb1e1211SMatthew G Knepley ierr = PetscSFReduceEnd (sf,MPIU_INT,lvisits,visits,MPI_SUM);CHKERRQ(ierr); 829cb1e1211SMatthew G Knepley ierr = PetscSFBcastBegin(sf,MPIU_INT,visits,lvisits);CHKERRQ(ierr); 830cb1e1211SMatthew G Knepley ierr = PetscSFBcastEnd (sf,MPIU_INT,visits,lvisits);CHKERRQ(ierr); 831cb1e1211SMatthew G Knepley 832cb1e1211SMatthew G Knepley ierr = PetscSFGetRanks();CHKERRQ(ierr); 833cb1e1211SMatthew G Knepley 834cb1e1211SMatthew G Knepley 835dcca6d9dSJed Brown ierr = PetscMalloc2(maxClosureSize*maxClosureSize,&cellmat,npoints,&owner);CHKERRQ(ierr); 836cb1e1211SMatthew G Knepley for (c=cStart; c<cEnd; c++) { 837cb1e1211SMatthew G Knepley ierr = PetscMemzero(cellmat,maxClosureSize*maxClosureSize*sizeof(PetscInt));CHKERRQ(ierr); 838cb1e1211SMatthew G Knepley /* 839cb1e1211SMatthew G Knepley Depth-first walk of transitive closure. 840cb1e1211SMatthew G Knepley At each leaf frame f of transitive closure that we see, add 1/visits[f] to each pair (p,q) not marked as done in cellmat. 841cb1e1211SMatthew G Knepley This contribution is added to dnz if owning ranks of p and q match, to onz otherwise. 842cb1e1211SMatthew G Knepley */ 843cb1e1211SMatthew G Knepley } 844cb1e1211SMatthew G Knepley 845cb1e1211SMatthew G Knepley ierr = PetscSFReduceBegin(sf,MPIU_INT,ldnz,dnz,MPI_SUM);CHKERRQ(ierr); 846cb1e1211SMatthew G Knepley ierr = PetscSFReduceEnd (sf,MPIU_INT,lonz,onz,MPI_SUM);CHKERRQ(ierr); 847cb1e1211SMatthew G Knepley PetscFunctionReturn(0); 848cb1e1211SMatthew G Knepley } 849cb1e1211SMatthew G Knepley #endif 850