1a8db3e61SBlaise Bourdin static char help[] = "Test FEM layout and GlobalToNaturalSF\n\n"; 2a8db3e61SBlaise Bourdin 3a8db3e61SBlaise Bourdin /* 4a8db3e61SBlaise Bourdin In order to see the vectors which are being tested, use 5a8db3e61SBlaise Bourdin 6a8db3e61SBlaise Bourdin -ua_vec_view -s_vec_view 7a8db3e61SBlaise Bourdin */ 8a8db3e61SBlaise Bourdin 9a8db3e61SBlaise Bourdin #include <petsc.h> 10a8db3e61SBlaise Bourdin #include <exodusII.h> 11a8db3e61SBlaise Bourdin 12a8db3e61SBlaise Bourdin #include <petsc/private/dmpleximpl.h> 13a8db3e61SBlaise Bourdin 14*d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 15*d71ae5a4SJacob Faibussowitsch { 16a8db3e61SBlaise Bourdin DM dm, pdm, dmU, dmA, dmS, dmUA, dmUA2, *dmList; 17a8db3e61SBlaise Bourdin DM seqdmU, seqdmA, seqdmS, seqdmUA, seqdmUA2, *seqdmList; 18a8db3e61SBlaise Bourdin Vec X, U, A, S, UA, UA2; 19a8db3e61SBlaise Bourdin Vec seqX, seqU, seqA, seqS, seqUA, seqUA2; 20a8db3e61SBlaise Bourdin IS isU, isA, isS, isUA; 21a8db3e61SBlaise Bourdin IS seqisU, seqisA, seqisS, seqisUA; 22a8db3e61SBlaise Bourdin PetscSection section; 23a8db3e61SBlaise Bourdin const PetscInt fieldU = 0; 24a8db3e61SBlaise Bourdin const PetscInt fieldA = 2; 25a8db3e61SBlaise Bourdin const PetscInt fieldS = 1; 26a8db3e61SBlaise Bourdin const PetscInt fieldUA[2] = {0, 2}; 27a8db3e61SBlaise Bourdin char ifilename[PETSC_MAX_PATH_LEN]; 28a8db3e61SBlaise Bourdin IS csIS; 29a8db3e61SBlaise Bourdin const PetscInt *csID; 30a8db3e61SBlaise Bourdin PetscInt *pStartDepth, *pEndDepth; 31a8db3e61SBlaise Bourdin PetscInt order = 1; 32a8db3e61SBlaise Bourdin PetscInt sdim, d, pStart, pEnd, p, numCS, set; 33a8db3e61SBlaise Bourdin PetscMPIInt rank, size; 34a8db3e61SBlaise Bourdin PetscSF migrationSF; 35a8db3e61SBlaise Bourdin 36a8db3e61SBlaise Bourdin PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 37a8db3e61SBlaise Bourdin PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 38a8db3e61SBlaise Bourdin PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 39a8db3e61SBlaise Bourdin PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "FEM Layout Options", "ex64"); 40a8db3e61SBlaise Bourdin PetscCall(PetscOptionsString("-i", "Filename to read", "ex64", ifilename, ifilename, sizeof(ifilename), NULL)); 41a8db3e61SBlaise Bourdin PetscOptionsEnd(); 42a8db3e61SBlaise Bourdin 43a8db3e61SBlaise Bourdin /* Read the mesh from a file in any supported format */ 44a8db3e61SBlaise Bourdin PetscCall(DMPlexCreateFromFile(PETSC_COMM_WORLD, ifilename, "ex64_plex", PETSC_TRUE, &dm)); 45a8db3e61SBlaise Bourdin PetscCall(DMPlexDistributeSetDefault(dm, PETSC_FALSE)); 46a8db3e61SBlaise Bourdin PetscCall(DMSetFromOptions(dm)); 47a8db3e61SBlaise Bourdin PetscCall(DMViewFromOptions(dm, NULL, "-dm_view")); 48a8db3e61SBlaise Bourdin PetscCall(DMGetDimension(dm, &sdim)); 49a8db3e61SBlaise Bourdin 50a8db3e61SBlaise Bourdin /* Create the main section containing all fields */ 51a8db3e61SBlaise Bourdin PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion)); 52a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetNumFields(section, 3)); 53a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetFieldName(section, fieldU, "U")); 54a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetFieldName(section, fieldA, "Alpha")); 55a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetFieldName(section, fieldS, "Sigma")); 56a8db3e61SBlaise Bourdin PetscCall(DMPlexGetChart(dm, &pStart, &pEnd)); 57a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetChart(section, pStart, pEnd)); 58a8db3e61SBlaise Bourdin PetscCall(PetscMalloc2(sdim + 1, &pStartDepth, sdim + 1, &pEndDepth)); 5948a46eb9SPierre Jolivet for (d = 0; d <= sdim; ++d) PetscCall(DMPlexGetDepthStratum(dm, d, &pStartDepth[d], &pEndDepth[d])); 60a8db3e61SBlaise Bourdin /* Vector field U, Scalar field Alpha, Tensor field Sigma */ 61a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetFieldComponents(section, fieldU, sdim)); 62a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetFieldComponents(section, fieldA, 1)); 63a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetFieldComponents(section, fieldS, sdim * (sdim + 1) / 2)); 64a8db3e61SBlaise Bourdin 65a8db3e61SBlaise Bourdin /* Going through cell sets then cells, and setting up storage for the sections */ 66a8db3e61SBlaise Bourdin PetscCall(DMGetLabelSize(dm, "Cell Sets", &numCS)); 67a8db3e61SBlaise Bourdin PetscCall(DMGetLabelIdIS(dm, "Cell Sets", &csIS)); 6848a46eb9SPierre Jolivet if (csIS) PetscCall(ISGetIndices(csIS, &csID)); 69a8db3e61SBlaise Bourdin for (set = 0; set < numCS; set++) { 70a8db3e61SBlaise Bourdin IS cellIS; 71a8db3e61SBlaise Bourdin const PetscInt *cellID; 72a8db3e61SBlaise Bourdin PetscInt numCells, cell, closureSize, *closureA = NULL; 73a8db3e61SBlaise Bourdin 74a8db3e61SBlaise Bourdin PetscCall(DMGetStratumSize(dm, "Cell Sets", csID[set], &numCells)); 75a8db3e61SBlaise Bourdin PetscCall(DMGetStratumIS(dm, "Cell Sets", csID[set], &cellIS)); 76a8db3e61SBlaise Bourdin if (numCells > 0) { 77a8db3e61SBlaise Bourdin /* dof layout ordered by increasing height in the DAG: cell, face, edge, vertex */ 78a8db3e61SBlaise Bourdin PetscInt dofUP1Tri[] = {2, 0, 0}; 79a8db3e61SBlaise Bourdin PetscInt dofAP1Tri[] = {1, 0, 0}; 80a8db3e61SBlaise Bourdin PetscInt dofUP2Tri[] = {2, 2, 0}; 81a8db3e61SBlaise Bourdin PetscInt dofAP2Tri[] = {1, 1, 0}; 82a8db3e61SBlaise Bourdin PetscInt dofUP1Quad[] = {2, 0, 0}; 83a8db3e61SBlaise Bourdin PetscInt dofAP1Quad[] = {1, 0, 0}; 84a8db3e61SBlaise Bourdin PetscInt dofUP2Quad[] = {2, 2, 2}; 85a8db3e61SBlaise Bourdin PetscInt dofAP2Quad[] = {1, 1, 1}; 86a8db3e61SBlaise Bourdin PetscInt dofS2D[] = {0, 0, 3}; 87a8db3e61SBlaise Bourdin PetscInt dofUP1Tet[] = {3, 0, 0, 0}; 88a8db3e61SBlaise Bourdin PetscInt dofAP1Tet[] = {1, 0, 0, 0}; 89a8db3e61SBlaise Bourdin PetscInt dofUP2Tet[] = {3, 3, 0, 0}; 90a8db3e61SBlaise Bourdin PetscInt dofAP2Tet[] = {1, 1, 0, 0}; 91a8db3e61SBlaise Bourdin PetscInt dofUP1Hex[] = {3, 0, 0, 0}; 92a8db3e61SBlaise Bourdin PetscInt dofAP1Hex[] = {1, 0, 0, 0}; 93a8db3e61SBlaise Bourdin PetscInt dofUP2Hex[] = {3, 3, 3, 3}; 94a8db3e61SBlaise Bourdin PetscInt dofAP2Hex[] = {1, 1, 1, 1}; 95a8db3e61SBlaise Bourdin PetscInt dofS3D[] = {0, 0, 0, 6}; 96a8db3e61SBlaise Bourdin PetscInt *dofU, *dofA, *dofS; 97a8db3e61SBlaise Bourdin 98a8db3e61SBlaise Bourdin switch (sdim) { 99*d71ae5a4SJacob Faibussowitsch case 2: 100*d71ae5a4SJacob Faibussowitsch dofS = dofS2D; 101*d71ae5a4SJacob Faibussowitsch break; 102*d71ae5a4SJacob Faibussowitsch case 3: 103*d71ae5a4SJacob Faibussowitsch dofS = dofS3D; 104*d71ae5a4SJacob Faibussowitsch break; 105*d71ae5a4SJacob Faibussowitsch default: 106*d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No layout for dimension %" PetscInt_FMT, sdim); 107a8db3e61SBlaise Bourdin } 108a8db3e61SBlaise Bourdin 109a8db3e61SBlaise Bourdin /* Identify cell type based on closure size only. This works for Tri/Tet/Quad/Hex meshes 110a8db3e61SBlaise Bourdin It will not be enough to identify more exotic elements like pyramid or prisms... */ 111a8db3e61SBlaise Bourdin PetscCall(ISGetIndices(cellIS, &cellID)); 112a8db3e61SBlaise Bourdin PetscCall(DMPlexGetTransitiveClosure(dm, cellID[0], PETSC_TRUE, &closureSize, &closureA)); 113a8db3e61SBlaise Bourdin switch (closureSize) { 114a8db3e61SBlaise Bourdin case 7: /* Tri */ 115a8db3e61SBlaise Bourdin if (order == 1) { 116a8db3e61SBlaise Bourdin dofU = dofUP1Tri; 117a8db3e61SBlaise Bourdin dofA = dofAP1Tri; 118a8db3e61SBlaise Bourdin } else { 119a8db3e61SBlaise Bourdin dofU = dofUP2Tri; 120a8db3e61SBlaise Bourdin dofA = dofAP2Tri; 121a8db3e61SBlaise Bourdin } 122a8db3e61SBlaise Bourdin break; 123a8db3e61SBlaise Bourdin case 9: /* Quad */ 124a8db3e61SBlaise Bourdin if (order == 1) { 125a8db3e61SBlaise Bourdin dofU = dofUP1Quad; 126a8db3e61SBlaise Bourdin dofA = dofAP1Quad; 127a8db3e61SBlaise Bourdin } else { 128a8db3e61SBlaise Bourdin dofU = dofUP2Quad; 129a8db3e61SBlaise Bourdin dofA = dofAP2Quad; 130a8db3e61SBlaise Bourdin } 131a8db3e61SBlaise Bourdin break; 132a8db3e61SBlaise Bourdin case 15: /* Tet */ 133a8db3e61SBlaise Bourdin if (order == 1) { 134a8db3e61SBlaise Bourdin dofU = dofUP1Tet; 135a8db3e61SBlaise Bourdin dofA = dofAP1Tet; 136a8db3e61SBlaise Bourdin } else { 137a8db3e61SBlaise Bourdin dofU = dofUP2Tet; 138a8db3e61SBlaise Bourdin dofA = dofAP2Tet; 139a8db3e61SBlaise Bourdin } 140a8db3e61SBlaise Bourdin break; 141a8db3e61SBlaise Bourdin case 27: /* Hex */ 142a8db3e61SBlaise Bourdin if (order == 1) { 143a8db3e61SBlaise Bourdin dofU = dofUP1Hex; 144a8db3e61SBlaise Bourdin dofA = dofAP1Hex; 145a8db3e61SBlaise Bourdin } else { 146a8db3e61SBlaise Bourdin dofU = dofUP2Hex; 147a8db3e61SBlaise Bourdin dofA = dofAP2Hex; 148a8db3e61SBlaise Bourdin } 149a8db3e61SBlaise Bourdin break; 150*d71ae5a4SJacob Faibussowitsch default: 151*d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Unknown element with closure size %" PetscInt_FMT, closureSize); 152a8db3e61SBlaise Bourdin } 153a8db3e61SBlaise Bourdin PetscCall(DMPlexRestoreTransitiveClosure(dm, cellID[0], PETSC_TRUE, &closureSize, &closureA)); 154a8db3e61SBlaise Bourdin 155a8db3e61SBlaise Bourdin for (cell = 0; cell < numCells; cell++) { 156a8db3e61SBlaise Bourdin PetscInt *closure = NULL; 157a8db3e61SBlaise Bourdin 158a8db3e61SBlaise Bourdin PetscCall(DMPlexGetTransitiveClosure(dm, cellID[cell], PETSC_TRUE, &closureSize, &closure)); 159a8db3e61SBlaise Bourdin for (p = 0; p < closureSize; ++p) { 160a8db3e61SBlaise Bourdin /* Find depth of p */ 161a8db3e61SBlaise Bourdin for (d = 0; d <= sdim; ++d) { 162a8db3e61SBlaise Bourdin if ((closure[2 * p] >= pStartDepth[d]) && (closure[2 * p] < pEndDepth[d])) { 163a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetDof(section, closure[2 * p], dofU[d] + dofA[d] + dofS[d])); 164a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetFieldDof(section, closure[2 * p], fieldU, dofU[d])); 165a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetFieldDof(section, closure[2 * p], fieldA, dofA[d])); 166a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetFieldDof(section, closure[2 * p], fieldS, dofS[d])); 167a8db3e61SBlaise Bourdin } 168a8db3e61SBlaise Bourdin } 169a8db3e61SBlaise Bourdin } 170a8db3e61SBlaise Bourdin PetscCall(DMPlexRestoreTransitiveClosure(dm, cellID[cell], PETSC_TRUE, &closureSize, &closure)); 171a8db3e61SBlaise Bourdin } 172a8db3e61SBlaise Bourdin PetscCall(ISRestoreIndices(cellIS, &cellID)); 173a8db3e61SBlaise Bourdin PetscCall(ISDestroy(&cellIS)); 174a8db3e61SBlaise Bourdin } 175a8db3e61SBlaise Bourdin } 17648a46eb9SPierre Jolivet if (csIS) PetscCall(ISRestoreIndices(csIS, &csID)); 177a8db3e61SBlaise Bourdin PetscCall(ISDestroy(&csIS)); 178a8db3e61SBlaise Bourdin PetscCall(PetscSectionSetUp(section)); 179a8db3e61SBlaise Bourdin PetscCall(DMSetLocalSection(dm, section)); 180a8db3e61SBlaise Bourdin PetscCall(PetscObjectViewFromOptions((PetscObject)section, NULL, "-dm_section_view")); 181a8db3e61SBlaise Bourdin PetscCall(PetscSectionDestroy(§ion)); 182a8db3e61SBlaise Bourdin 183a8db3e61SBlaise Bourdin /* Get DM and IS for each field of dm */ 184a8db3e61SBlaise Bourdin PetscCall(DMCreateSubDM(dm, 1, &fieldU, &seqisU, &seqdmU)); 185a8db3e61SBlaise Bourdin PetscCall(DMCreateSubDM(dm, 1, &fieldA, &seqisA, &seqdmA)); 186a8db3e61SBlaise Bourdin PetscCall(DMCreateSubDM(dm, 1, &fieldS, &seqisS, &seqdmS)); 187a8db3e61SBlaise Bourdin PetscCall(DMCreateSubDM(dm, 2, fieldUA, &seqisUA, &seqdmUA)); 188a8db3e61SBlaise Bourdin 189a8db3e61SBlaise Bourdin PetscCall(PetscMalloc1(2, &seqdmList)); 190a8db3e61SBlaise Bourdin seqdmList[0] = seqdmU; 191a8db3e61SBlaise Bourdin seqdmList[1] = seqdmA; 192a8db3e61SBlaise Bourdin 193a8db3e61SBlaise Bourdin PetscCall(DMCreateSuperDM(seqdmList, 2, NULL, &seqdmUA2)); 194a8db3e61SBlaise Bourdin PetscCall(PetscFree(seqdmList)); 195a8db3e61SBlaise Bourdin 196a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(dm, &seqX)); 197a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(seqdmU, &seqU)); 198a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(seqdmA, &seqA)); 199a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(seqdmS, &seqS)); 200a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(seqdmUA, &seqUA)); 201a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(seqdmUA2, &seqUA2)); 202a8db3e61SBlaise Bourdin 203a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)seqX, "seqX")); 204a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)seqU, "seqU")); 205a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)seqA, "seqAlpha")); 206a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)seqS, "seqSigma")); 207a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)seqUA, "seqUAlpha")); 208a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)seqUA2, "seqUAlpha2")); 209a8db3e61SBlaise Bourdin PetscCall(VecSet(seqX, -111.)); 210a8db3e61SBlaise Bourdin 211a8db3e61SBlaise Bourdin /* Setting u to [x,y,z] and alpha to x^2+y^2+z^2 by writing in UAlpha then restricting to U and Alpha */ 212a8db3e61SBlaise Bourdin { 213a8db3e61SBlaise Bourdin PetscSection sectionUA; 214a8db3e61SBlaise Bourdin Vec UALoc; 215a8db3e61SBlaise Bourdin PetscSection coordSection; 216a8db3e61SBlaise Bourdin Vec coord; 217a8db3e61SBlaise Bourdin PetscScalar *cval, *xyz; 218a8db3e61SBlaise Bourdin PetscInt clSize, i, j; 219a8db3e61SBlaise Bourdin 220a8db3e61SBlaise Bourdin PetscCall(DMGetLocalSection(seqdmUA, §ionUA)); 221a8db3e61SBlaise Bourdin PetscCall(DMGetLocalVector(seqdmUA, &UALoc)); 222a8db3e61SBlaise Bourdin PetscCall(VecGetArray(UALoc, &cval)); 223a8db3e61SBlaise Bourdin PetscCall(DMGetCoordinateSection(seqdmUA, &coordSection)); 224a8db3e61SBlaise Bourdin PetscCall(DMGetCoordinatesLocal(seqdmUA, &coord)); 225a8db3e61SBlaise Bourdin PetscCall(DMPlexGetChart(seqdmUA, &pStart, &pEnd)); 226a8db3e61SBlaise Bourdin 227a8db3e61SBlaise Bourdin for (p = pStart; p < pEnd; ++p) { 228a8db3e61SBlaise Bourdin PetscInt dofUA, offUA; 229a8db3e61SBlaise Bourdin 230a8db3e61SBlaise Bourdin PetscCall(PetscSectionGetDof(sectionUA, p, &dofUA)); 231a8db3e61SBlaise Bourdin if (dofUA > 0) { 232a8db3e61SBlaise Bourdin xyz = NULL; 233a8db3e61SBlaise Bourdin PetscCall(PetscSectionGetOffset(sectionUA, p, &offUA)); 234a8db3e61SBlaise Bourdin PetscCall(DMPlexVecGetClosure(seqdmUA, coordSection, coord, p, &clSize, &xyz)); 235a8db3e61SBlaise Bourdin cval[offUA + sdim] = 0.; 236a8db3e61SBlaise Bourdin for (i = 0; i < sdim; ++i) { 237a8db3e61SBlaise Bourdin cval[offUA + i] = 0; 238ad540459SPierre Jolivet for (j = 0; j < clSize / sdim; ++j) cval[offUA + i] += xyz[j * sdim + i]; 239a8db3e61SBlaise Bourdin cval[offUA + i] = cval[offUA + i] * sdim / clSize; 240a8db3e61SBlaise Bourdin cval[offUA + sdim] += PetscSqr(cval[offUA + i]); 241a8db3e61SBlaise Bourdin } 242a8db3e61SBlaise Bourdin PetscCall(DMPlexVecRestoreClosure(seqdmUA, coordSection, coord, p, &clSize, &xyz)); 243a8db3e61SBlaise Bourdin } 244a8db3e61SBlaise Bourdin } 245a8db3e61SBlaise Bourdin PetscCall(VecRestoreArray(UALoc, &cval)); 246a8db3e61SBlaise Bourdin PetscCall(DMLocalToGlobalBegin(seqdmUA, UALoc, INSERT_VALUES, seqUA)); 247a8db3e61SBlaise Bourdin PetscCall(DMLocalToGlobalEnd(seqdmUA, UALoc, INSERT_VALUES, seqUA)); 248a8db3e61SBlaise Bourdin PetscCall(DMRestoreLocalVector(seqdmUA, &UALoc)); 249a8db3e61SBlaise Bourdin 250a8db3e61SBlaise Bourdin /* Update X */ 251a8db3e61SBlaise Bourdin PetscCall(VecISCopy(seqX, seqisUA, SCATTER_FORWARD, seqUA)); 252a8db3e61SBlaise Bourdin PetscCall(VecViewFromOptions(seqUA, NULL, "-ua_vec_view")); 253a8db3e61SBlaise Bourdin 254a8db3e61SBlaise Bourdin /* Restrict to U and Alpha */ 255a8db3e61SBlaise Bourdin PetscCall(VecISCopy(seqX, seqisU, SCATTER_REVERSE, seqU)); 256a8db3e61SBlaise Bourdin PetscCall(VecISCopy(seqX, seqisA, SCATTER_REVERSE, seqA)); 257a8db3e61SBlaise Bourdin 258a8db3e61SBlaise Bourdin /* restrict to UA2 */ 259a8db3e61SBlaise Bourdin PetscCall(VecISCopy(seqX, seqisUA, SCATTER_REVERSE, seqUA2)); 260a8db3e61SBlaise Bourdin PetscCall(VecViewFromOptions(seqUA2, NULL, "-ua2_vec_view")); 261a8db3e61SBlaise Bourdin } 262a8db3e61SBlaise Bourdin 263a8db3e61SBlaise Bourdin { 264a8db3e61SBlaise Bourdin PetscInt ovlp = 0; 265a8db3e61SBlaise Bourdin PetscPartitioner part; 266a8db3e61SBlaise Bourdin 267a8db3e61SBlaise Bourdin PetscCall(DMSetUseNatural(dm, PETSC_TRUE)); 268a8db3e61SBlaise Bourdin PetscCall(DMPlexGetPartitioner(dm, &part)); 269a8db3e61SBlaise Bourdin PetscCall(PetscPartitionerSetFromOptions(part)); 270a8db3e61SBlaise Bourdin PetscCall(DMPlexDistribute(dm, ovlp, &migrationSF, &pdm)); 271a8db3e61SBlaise Bourdin if (!pdm) pdm = dm; 272a8db3e61SBlaise Bourdin if (migrationSF) { 273a8db3e61SBlaise Bourdin PetscCall(DMPlexSetMigrationSF(pdm, migrationSF)); 274a8db3e61SBlaise Bourdin PetscCall(PetscSFDestroy(&migrationSF)); 275a8db3e61SBlaise Bourdin } 276a8db3e61SBlaise Bourdin PetscCall(DMViewFromOptions(pdm, NULL, "-dm_view")); 277a8db3e61SBlaise Bourdin } 278a8db3e61SBlaise Bourdin 279a8db3e61SBlaise Bourdin /* Get DM and IS for each field of dm */ 280a8db3e61SBlaise Bourdin PetscCall(DMCreateSubDM(pdm, 1, &fieldU, &isU, &dmU)); 281a8db3e61SBlaise Bourdin PetscCall(DMCreateSubDM(pdm, 1, &fieldA, &isA, &dmA)); 282a8db3e61SBlaise Bourdin PetscCall(DMCreateSubDM(pdm, 1, &fieldS, &isS, &dmS)); 283a8db3e61SBlaise Bourdin PetscCall(DMCreateSubDM(pdm, 2, fieldUA, &isUA, &dmUA)); 284a8db3e61SBlaise Bourdin 285a8db3e61SBlaise Bourdin PetscCall(PetscMalloc1(2, &dmList)); 286a8db3e61SBlaise Bourdin dmList[0] = dmU; 287a8db3e61SBlaise Bourdin dmList[1] = dmA; 288a8db3e61SBlaise Bourdin 289a8db3e61SBlaise Bourdin PetscCall(DMCreateSuperDM(dmList, 2, NULL, &dmUA2)); 290a8db3e61SBlaise Bourdin PetscCall(PetscFree(dmList)); 291a8db3e61SBlaise Bourdin 292a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(pdm, &X)); 293a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(dmU, &U)); 294a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(dmA, &A)); 295a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(dmS, &S)); 296a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(dmUA, &UA)); 297a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(dmUA2, &UA2)); 298a8db3e61SBlaise Bourdin 299a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)X, "X")); 300a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)U, "U")); 301a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)A, "Alpha")); 302a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)S, "Sigma")); 303a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)UA, "UAlpha")); 304a8db3e61SBlaise Bourdin PetscCall(PetscObjectSetName((PetscObject)UA2, "UAlpha2")); 305a8db3e61SBlaise Bourdin PetscCall(VecSet(X, -111.)); 306a8db3e61SBlaise Bourdin 307a8db3e61SBlaise Bourdin /* Setting u to [x,y,z] and alpha to x^2+y^2+z^2 by writing in UAlpha then restricting to U and Alpha */ 308a8db3e61SBlaise Bourdin { 309a8db3e61SBlaise Bourdin PetscSection sectionUA; 310a8db3e61SBlaise Bourdin Vec UALoc; 311a8db3e61SBlaise Bourdin PetscSection coordSection; 312a8db3e61SBlaise Bourdin Vec coord; 313a8db3e61SBlaise Bourdin PetscScalar *cval, *xyz; 314a8db3e61SBlaise Bourdin PetscInt clSize, i, j; 315a8db3e61SBlaise Bourdin 316a8db3e61SBlaise Bourdin PetscCall(DMGetLocalSection(dmUA, §ionUA)); 317a8db3e61SBlaise Bourdin PetscCall(DMGetLocalVector(dmUA, &UALoc)); 318a8db3e61SBlaise Bourdin PetscCall(VecGetArray(UALoc, &cval)); 319a8db3e61SBlaise Bourdin PetscCall(DMGetCoordinateSection(dmUA, &coordSection)); 320a8db3e61SBlaise Bourdin PetscCall(DMGetCoordinatesLocal(dmUA, &coord)); 321a8db3e61SBlaise Bourdin PetscCall(DMPlexGetChart(dmUA, &pStart, &pEnd)); 322a8db3e61SBlaise Bourdin 323a8db3e61SBlaise Bourdin for (p = pStart; p < pEnd; ++p) { 324a8db3e61SBlaise Bourdin PetscInt dofUA, offUA; 325a8db3e61SBlaise Bourdin 326a8db3e61SBlaise Bourdin PetscCall(PetscSectionGetDof(sectionUA, p, &dofUA)); 327a8db3e61SBlaise Bourdin if (dofUA > 0) { 328a8db3e61SBlaise Bourdin xyz = NULL; 329a8db3e61SBlaise Bourdin PetscCall(PetscSectionGetOffset(sectionUA, p, &offUA)); 330a8db3e61SBlaise Bourdin PetscCall(DMPlexVecGetClosure(dmUA, coordSection, coord, p, &clSize, &xyz)); 331a8db3e61SBlaise Bourdin cval[offUA + sdim] = 0.; 332a8db3e61SBlaise Bourdin for (i = 0; i < sdim; ++i) { 333a8db3e61SBlaise Bourdin cval[offUA + i] = 0; 334ad540459SPierre Jolivet for (j = 0; j < clSize / sdim; ++j) cval[offUA + i] += xyz[j * sdim + i]; 335a8db3e61SBlaise Bourdin cval[offUA + i] = cval[offUA + i] * sdim / clSize; 336a8db3e61SBlaise Bourdin cval[offUA + sdim] += PetscSqr(cval[offUA + i]); 337a8db3e61SBlaise Bourdin } 338a8db3e61SBlaise Bourdin PetscCall(DMPlexVecRestoreClosure(dmUA, coordSection, coord, p, &clSize, &xyz)); 339a8db3e61SBlaise Bourdin } 340a8db3e61SBlaise Bourdin } 341a8db3e61SBlaise Bourdin PetscCall(VecRestoreArray(UALoc, &cval)); 342a8db3e61SBlaise Bourdin PetscCall(DMLocalToGlobalBegin(dmUA, UALoc, INSERT_VALUES, UA)); 343a8db3e61SBlaise Bourdin PetscCall(DMLocalToGlobalEnd(dmUA, UALoc, INSERT_VALUES, UA)); 344a8db3e61SBlaise Bourdin PetscCall(DMRestoreLocalVector(dmUA, &UALoc)); 345a8db3e61SBlaise Bourdin 346a8db3e61SBlaise Bourdin /* Update X */ 347a8db3e61SBlaise Bourdin PetscCall(VecISCopy(X, isUA, SCATTER_FORWARD, UA)); 348a8db3e61SBlaise Bourdin PetscCall(VecViewFromOptions(UA, NULL, "-ua_vec_view")); 349a8db3e61SBlaise Bourdin 350a8db3e61SBlaise Bourdin /* Restrict to U and Alpha */ 351a8db3e61SBlaise Bourdin PetscCall(VecISCopy(X, isU, SCATTER_REVERSE, U)); 352a8db3e61SBlaise Bourdin PetscCall(VecISCopy(X, isA, SCATTER_REVERSE, A)); 353a8db3e61SBlaise Bourdin 354a8db3e61SBlaise Bourdin /* restrict to UA2 */ 355a8db3e61SBlaise Bourdin PetscCall(VecISCopy(X, isUA, SCATTER_REVERSE, UA2)); 356a8db3e61SBlaise Bourdin PetscCall(VecViewFromOptions(UA2, NULL, "-ua2_vec_view")); 357a8db3e61SBlaise Bourdin } 358a8db3e61SBlaise Bourdin 359a8db3e61SBlaise Bourdin /* Verification */ 360a8db3e61SBlaise Bourdin 361a8db3e61SBlaise Bourdin Vec Xnat, Unat, Anat, UAnat, Snat, UA2nat; 362a8db3e61SBlaise Bourdin PetscReal norm; 363a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(dm, &Xnat)); 364a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(seqdmU, &Unat)); 365a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(seqdmA, &Anat)); 366a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(seqdmUA, &UAnat)); 367a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(seqdmS, &Snat)); 368a8db3e61SBlaise Bourdin PetscCall(DMGetGlobalVector(seqdmUA2, &UA2nat)); 369a8db3e61SBlaise Bourdin 370a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalBegin(pdm, X, Xnat)); 371a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalEnd(pdm, X, Xnat)); 372a8db3e61SBlaise Bourdin PetscCall(VecAXPY(Xnat, -1.0, seqX)); 373a8db3e61SBlaise Bourdin PetscCall(VecNorm(Xnat, NORM_INFINITY, &norm)); 374a8db3e61SBlaise Bourdin PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "X ||Vin - Vout|| = %g", (double)norm); 375a8db3e61SBlaise Bourdin 376a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalBegin(dmU, U, Unat)); 377a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalEnd(dmU, U, Unat)); 378a8db3e61SBlaise Bourdin PetscCall(VecAXPY(Unat, -1.0, seqU)); 379a8db3e61SBlaise Bourdin PetscCall(VecNorm(Unat, NORM_INFINITY, &norm)); 380a8db3e61SBlaise Bourdin PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "U ||Vin - Vout|| = %g", (double)norm); 381a8db3e61SBlaise Bourdin 382a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalBegin(dmA, A, Anat)); 383a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalEnd(dmA, A, Anat)); 384a8db3e61SBlaise Bourdin PetscCall(VecAXPY(Anat, -1.0, seqA)); 385a8db3e61SBlaise Bourdin PetscCall(VecNorm(Anat, NORM_INFINITY, &norm)); 386a8db3e61SBlaise Bourdin PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "A ||Vin - Vout|| = %g", (double)norm); 387a8db3e61SBlaise Bourdin 388a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalBegin(dmUA, UA, UAnat)); 389a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalEnd(dmUA, UA, UAnat)); 390a8db3e61SBlaise Bourdin PetscCall(VecAXPY(UAnat, -1.0, seqUA)); 391a8db3e61SBlaise Bourdin PetscCall(VecNorm(UAnat, NORM_INFINITY, &norm)); 392a8db3e61SBlaise Bourdin PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "UA ||Vin - Vout|| = %g", (double)norm); 393a8db3e61SBlaise Bourdin 394a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalBegin(dmS, S, Snat)); 395a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalEnd(dmS, S, Snat)); 396a8db3e61SBlaise Bourdin PetscCall(VecAXPY(Snat, -1.0, seqS)); 397a8db3e61SBlaise Bourdin PetscCall(VecNorm(Snat, NORM_INFINITY, &norm)); 398a8db3e61SBlaise Bourdin PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "S ||Vin - Vout|| = %g", (double)norm); 399a8db3e61SBlaise Bourdin 400a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalBegin(dmUA2, UA2, UA2nat)); 401a8db3e61SBlaise Bourdin PetscCall(DMPlexGlobalToNaturalEnd(dmUA2, UA2, UA2nat)); 402a8db3e61SBlaise Bourdin PetscCall(VecAXPY(UA2nat, -1.0, seqUA2)); 403a8db3e61SBlaise Bourdin PetscCall(VecNorm(UA2nat, NORM_INFINITY, &norm)); 404a8db3e61SBlaise Bourdin PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "UAlpha2 ||Vin - Vout|| = %g", (double)norm); 405a8db3e61SBlaise Bourdin 406a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(dm, &Xnat)); 407a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(seqdmU, &Unat)); 408a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(seqdmA, &Anat)); 409a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(seqdmUA, &UAnat)); 410a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(seqdmS, &Snat)); 411a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(seqdmUA2, &UA2nat)); 412a8db3e61SBlaise Bourdin 413a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(seqdmUA2, &seqUA2)); 414a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(seqdmUA, &seqUA)); 415a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(seqdmS, &seqS)); 416a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(seqdmA, &seqA)); 417a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(seqdmU, &seqU)); 418a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(dm, &seqX)); 4199371c9d4SSatish Balay PetscCall(DMDestroy(&seqdmU)); 4209371c9d4SSatish Balay PetscCall(ISDestroy(&seqisU)); 4219371c9d4SSatish Balay PetscCall(DMDestroy(&seqdmA)); 4229371c9d4SSatish Balay PetscCall(ISDestroy(&seqisA)); 4239371c9d4SSatish Balay PetscCall(DMDestroy(&seqdmS)); 4249371c9d4SSatish Balay PetscCall(ISDestroy(&seqisS)); 4259371c9d4SSatish Balay PetscCall(DMDestroy(&seqdmUA)); 4269371c9d4SSatish Balay PetscCall(ISDestroy(&seqisUA)); 427a8db3e61SBlaise Bourdin PetscCall(DMDestroy(&seqdmUA2)); 428a8db3e61SBlaise Bourdin 429a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(dmUA2, &UA2)); 430a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(dmUA, &UA)); 431a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(dmS, &S)); 432a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(dmA, &A)); 433a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(dmU, &U)); 434a8db3e61SBlaise Bourdin PetscCall(DMRestoreGlobalVector(pdm, &X)); 4359371c9d4SSatish Balay PetscCall(DMDestroy(&dmU)); 4369371c9d4SSatish Balay PetscCall(ISDestroy(&isU)); 4379371c9d4SSatish Balay PetscCall(DMDestroy(&dmA)); 4389371c9d4SSatish Balay PetscCall(ISDestroy(&isA)); 4399371c9d4SSatish Balay PetscCall(DMDestroy(&dmS)); 4409371c9d4SSatish Balay PetscCall(ISDestroy(&isS)); 4419371c9d4SSatish Balay PetscCall(DMDestroy(&dmUA)); 4429371c9d4SSatish Balay PetscCall(ISDestroy(&isUA)); 443a8db3e61SBlaise Bourdin PetscCall(DMDestroy(&dmUA2)); 444a8db3e61SBlaise Bourdin PetscCall(DMDestroy(&pdm)); 445a8db3e61SBlaise Bourdin if (size > 1) PetscCall(DMDestroy(&dm)); 446a8db3e61SBlaise Bourdin PetscCall(PetscFree2(pStartDepth, pEndDepth)); 447a8db3e61SBlaise Bourdin PetscCall(PetscFinalize()); 448a8db3e61SBlaise Bourdin return 0; 449a8db3e61SBlaise Bourdin } 450a8db3e61SBlaise Bourdin 451a8db3e61SBlaise Bourdin /*TEST 452a8db3e61SBlaise Bourdin 453a8db3e61SBlaise Bourdin build: 454a8db3e61SBlaise Bourdin requires: !complex parmetis exodusii pnetcdf 455a8db3e61SBlaise Bourdin # 2D seq 456a8db3e61SBlaise Bourdin test: 457a8db3e61SBlaise Bourdin suffix: 0 458a8db3e61SBlaise Bourdin args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareT-large.exo -dm_view -petscpartitioner_type parmetis 459a8db3e61SBlaise Bourdin test: 460a8db3e61SBlaise Bourdin suffix: 1 461a8db3e61SBlaise Bourdin args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareQ-large.exo -dm_view -petscpartitioner_type parmetis 462a8db3e61SBlaise Bourdin test: 463a8db3e61SBlaise Bourdin suffix: 2 464a8db3e61SBlaise Bourdin args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareH-large.exo -dm_view -petscpartitioner_type parmetis 465a8db3e61SBlaise Bourdin 466a8db3e61SBlaise Bourdin # 2D par 467a8db3e61SBlaise Bourdin test: 468a8db3e61SBlaise Bourdin suffix: 3 469a8db3e61SBlaise Bourdin nsize: 2 470a8db3e61SBlaise Bourdin args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareT-large.exo -dm_view -petscpartitioner_type parmetis 471a8db3e61SBlaise Bourdin test: 472a8db3e61SBlaise Bourdin suffix: 4 473a8db3e61SBlaise Bourdin nsize: 2 474a8db3e61SBlaise Bourdin args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareQ-large.exo -dm_view -petscpartitioner_type parmetis 475a8db3e61SBlaise Bourdin test: 476a8db3e61SBlaise Bourdin suffix: 5 477a8db3e61SBlaise Bourdin nsize: 2 478a8db3e61SBlaise Bourdin args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareH-large.exo -dm_view -petscpartitioner_type parmetis 479a8db3e61SBlaise Bourdin 480a8db3e61SBlaise Bourdin #3d seq 481a8db3e61SBlaise Bourdin test: 482a8db3e61SBlaise Bourdin suffix: 6 483a8db3e61SBlaise Bourdin args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourBrickHex-large.exo -dm_view -petscpartitioner_type parmetis 484a8db3e61SBlaise Bourdin test: 485a8db3e61SBlaise Bourdin suffix: 7 486a8db3e61SBlaise Bourdin args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourBrickTet-large.exo -dm_view -petscpartitioner_type parmetis 487a8db3e61SBlaise Bourdin 488a8db3e61SBlaise Bourdin #3d par 489a8db3e61SBlaise Bourdin test: 490a8db3e61SBlaise Bourdin suffix: 8 491a8db3e61SBlaise Bourdin nsize: 2 492a8db3e61SBlaise Bourdin args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourBrickHex-large.exo -dm_view -petscpartitioner_type parmetis 493a8db3e61SBlaise Bourdin test: 494a8db3e61SBlaise Bourdin suffix: 9 495a8db3e61SBlaise Bourdin nsize: 2 496a8db3e61SBlaise Bourdin args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourBrickTet-large.exo -dm_view -petscpartitioner_type parmetis 497a8db3e61SBlaise Bourdin 498a8db3e61SBlaise Bourdin TEST*/ 499