Date: 2026-05-01T06:11:52+00:00

Actual source code: ex85.c

      1: static char help[] = "Demonstration of flexible submesh assembly.\n\n";

      3: #include <petscksp.h>

      5: int main(int argc, char **argv)
      6: {
      7:   Mat                    G, A, B, C, D;
      8:   ISLocalToGlobalMapping rowMap, colMap;
      9:   IS                     row, col;
     10:   PetscInt              *locRows, *locCols;
     11:   PetscInt               m = 5, n = 5, M = PETSC_DETERMINE, N = PETSC_DETERMINE, rStart, cStart;
     12:   PetscBool              isnest;

     14:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
     15:   // Fill up blocks with local lexicographic numbering
     16:   PetscCall(PetscSplitOwnership(PETSC_COMM_WORLD, &m, &M));
     17:   PetscCall(PetscSplitOwnership(PETSC_COMM_WORLD, &n, &N));
     18:   PetscCall(MatCreate(PETSC_COMM_WORLD, &G));
     19:   PetscCall(MatSetSizes(G, m, n, M, N));
     20:   PetscCall(MatSetFromOptions(G));
     21:   PetscCall(PetscObjectTypeCompare((PetscObject)G, MATNEST, &isnest));
     22:   PetscCall(MatGetOwnershipRange(G, &rStart, NULL));
     23:   PetscCall(MatGetOwnershipRangeColumn(G, &cStart, NULL));
     24:   if (isnest) {
     25:     Mat                    submat[4];
     26:     PetscLayout            layoutA, layoutD;
     27:     PetscInt              *locRowsA, *locColsA, *locRowsD, *locColsD, rStartA, rStartD;
     28:     ISLocalToGlobalMapping rowMapA, colMapA, rowMapD, colMapD;

     30:     PetscCall(PetscLayoutCreate(PETSC_COMM_WORLD, &layoutA));
     31:     PetscCall(PetscLayoutSetLocalSize(layoutA, 3));
     32:     PetscCall(PetscLayoutSetUp(layoutA));
     33:     PetscCall(PetscLayoutGetRange(layoutA, &rStartA, NULL));
     34:     PetscCall(PetscLayoutDestroy(&layoutA));
     35:     PetscCall(PetscMalloc1(3, &locRowsA));
     36:     for (PetscInt r = 0; r < 3; ++r) locRowsA[r] = r + rStartA;
     37:     PetscCall(PetscMalloc1(3, &locColsA));
     38:     for (PetscInt c = 0; c < 3; ++c) locColsA[c] = c + rStartA;
     39:     PetscCall(ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD, 1, 3, locRowsA, PETSC_OWN_POINTER, &rowMapA));
     40:     PetscCall(ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD, 1, 3, locColsA, PETSC_OWN_POINTER, &colMapA));
     41:     PetscCall(PetscLayoutCreate(PETSC_COMM_WORLD, &layoutD));
     42:     PetscCall(PetscLayoutSetLocalSize(layoutD, 2));
     43:     PetscCall(PetscLayoutSetUp(layoutD));
     44:     PetscCall(PetscLayoutGetRange(layoutD, &rStartD, NULL));
     45:     PetscCall(PetscLayoutDestroy(&layoutD));
     46:     PetscCall(PetscMalloc1(2, &locRowsD));
     47:     for (PetscInt r = 0; r < 2; ++r) locRowsD[r] = r + rStartD;
     48:     PetscCall(PetscMalloc1(2, &locColsD));
     49:     for (PetscInt c = 0; c < 2; ++c) locColsD[c] = c + rStartD;
     50:     PetscCall(ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD, 1, 2, locRowsD, PETSC_OWN_POINTER, &rowMapD));
     51:     PetscCall(ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD, 1, 2, locColsD, PETSC_OWN_POINTER, &colMapD));

     53:     PetscCall(MatCreate(PETSC_COMM_WORLD, &submat[0]));
     54:     PetscCall(MatSetSizes(submat[0], 3, 3, PETSC_DETERMINE, PETSC_DETERMINE));
     55:     PetscCall(MatSetType(submat[0], MATAIJ));
     56:     PetscCall(MatSetLocalToGlobalMapping(submat[0], rowMapA, colMapA));
     57:     PetscCall(MatCreate(PETSC_COMM_WORLD, &submat[1]));
     58:     PetscCall(MatSetSizes(submat[1], 3, 2, PETSC_DETERMINE, PETSC_DETERMINE));
     59:     PetscCall(MatSetType(submat[1], MATAIJ));
     60:     PetscCall(MatSetLocalToGlobalMapping(submat[1], rowMapA, colMapD));
     61:     PetscCall(MatCreate(PETSC_COMM_WORLD, &submat[2]));
     62:     PetscCall(MatSetSizes(submat[2], 2, 3, PETSC_DETERMINE, PETSC_DETERMINE));
     63:     PetscCall(MatSetType(submat[2], MATAIJ));
     64:     PetscCall(MatSetLocalToGlobalMapping(submat[2], rowMapD, colMapA));
     65:     PetscCall(MatCreate(PETSC_COMM_WORLD, &submat[3]));
     66:     PetscCall(MatSetSizes(submat[3], 2, 2, PETSC_DETERMINE, PETSC_DETERMINE));
     67:     PetscCall(MatSetType(submat[3], MATAIJ));
     68:     PetscCall(MatSetLocalToGlobalMapping(submat[3], rowMapD, colMapD));
     69:     for (PetscInt i = 0; i < 4; ++i) PetscCall(MatSetUp(submat[i]));
     70:     PetscCall(MatNestSetSubMats(G, 2, NULL, 2, NULL, submat));
     71:     for (PetscInt i = 0; i < 4; ++i) PetscCall(MatDestroy(&submat[i]));

     73:     PetscCall(ISLocalToGlobalMappingDestroy(&rowMapA));
     74:     PetscCall(ISLocalToGlobalMappingDestroy(&colMapA));
     75:     PetscCall(ISLocalToGlobalMappingDestroy(&rowMapD));
     76:     PetscCall(ISLocalToGlobalMappingDestroy(&colMapD));
     77:   }
     78:   PetscCall(PetscMalloc1(m, &locRows));
     79:   for (PetscInt r = 0; r < m; ++r) locRows[r] = r + rStart;
     80:   PetscCall(PetscMalloc1(n, &locCols));
     81:   for (PetscInt c = 0; c < n; ++c) locCols[c] = c + cStart;
     82:   PetscCall(ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD, 1, m, locRows, PETSC_OWN_POINTER, &rowMap));
     83:   PetscCall(ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD, 1, n, locCols, PETSC_OWN_POINTER, &colMap));
     84:   PetscCall(MatSetLocalToGlobalMapping(G, rowMap, colMap));
     85:   PetscCall(ISLocalToGlobalMappingDestroy(&rowMap));
     86:   PetscCall(ISLocalToGlobalMappingDestroy(&colMap));

     88:   // (0,0) Block A
     89:   PetscInt A_row[] = {0, 1, 2};
     90:   PetscInt A_col[] = {0, 1, 2};

     92:   m = PETSC_STATIC_ARRAY_LENGTH(A_row);
     93:   n = PETSC_STATIC_ARRAY_LENGTH(A_col);
     94:   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, m, A_row, PETSC_COPY_VALUES, &row));
     95:   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, n, A_col, PETSC_COPY_VALUES, &col));
     96:   PetscCall(MatGetLocalSubMatrix(G, row, col, &A));
     97:   PetscCall(ISDestroy(&row));
     98:   PetscCall(ISDestroy(&col));
     99:   for (PetscInt i = 0; i < m; ++i) {
    100:     for (PetscInt j = 0; j < n; ++j) {
    101:       PetscScalar v = i * n + j;

    103:       PetscCall(MatSetValuesLocal(A, 1, &i, 1, &j, &v, INSERT_VALUES));
    104:     }
    105:   }
    106:   PetscCall(MatDestroy(&A));

    108:   // (0,1) Block B
    109:   PetscInt B_row[] = {0, 1, 2};
    110:   PetscInt B_col[] = {3, 4};

    112:   m = PETSC_STATIC_ARRAY_LENGTH(B_row);
    113:   n = PETSC_STATIC_ARRAY_LENGTH(B_col);
    114:   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, m, B_row, PETSC_COPY_VALUES, &row));
    115:   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, n, B_col, PETSC_COPY_VALUES, &col));
    116:   PetscCall(MatGetLocalSubMatrix(G, row, col, &B));
    117:   PetscCall(ISDestroy(&row));
    118:   PetscCall(ISDestroy(&col));
    119:   for (PetscInt i = 0; i < m; ++i) {
    120:     for (PetscInt j = 0; j < n; ++j) {
    121:       PetscScalar v = i * n + j;

    123:       PetscCall(MatSetValuesLocal(B, 1, &i, 1, &j, &v, INSERT_VALUES));
    124:     }
    125:   }
    126:   PetscCall(MatDestroy(&B));

    128:   // (0,1) Block C
    129:   PetscInt C_row[] = {3, 4};
    130:   PetscInt C_col[] = {0, 1, 2};

    132:   m = PETSC_STATIC_ARRAY_LENGTH(C_row);
    133:   n = PETSC_STATIC_ARRAY_LENGTH(C_col);
    134:   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, m, C_row, PETSC_COPY_VALUES, &row));
    135:   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, n, C_col, PETSC_COPY_VALUES, &col));
    136:   PetscCall(MatGetLocalSubMatrix(G, row, col, &C));
    137:   PetscCall(ISDestroy(&row));
    138:   PetscCall(ISDestroy(&col));
    139:   for (PetscInt i = 0; i < m; ++i) {
    140:     for (PetscInt j = 0; j < n; ++j) {
    141:       PetscScalar v = i * n + j;

    143:       PetscCall(MatSetValuesLocal(C, 1, &i, 1, &j, &v, INSERT_VALUES));
    144:     }
    145:   }
    146:   PetscCall(MatDestroy(&C));

    148:   // (0,0) Block D
    149:   PetscInt D_row[] = {3, 4};
    150:   PetscInt D_col[] = {3, 4};

    152:   m = PETSC_STATIC_ARRAY_LENGTH(D_row);
    153:   n = PETSC_STATIC_ARRAY_LENGTH(D_col);
    154:   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, m, D_row, PETSC_COPY_VALUES, &row));
    155:   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, n, D_col, PETSC_COPY_VALUES, &col));
    156:   PetscCall(MatGetLocalSubMatrix(G, row, col, &D));
    157:   PetscCall(ISDestroy(&row));
    158:   PetscCall(ISDestroy(&col));
    159:   for (PetscInt i = 0; i < m; ++i) {
    160:     for (PetscInt j = 0; j < n; ++j) {
    161:       PetscScalar v = i * n + j;

    163:       PetscCall(MatSetValuesLocal(D, 1, &i, 1, &j, &v, INSERT_VALUES));
    164:     }
    165:   }
    166:   PetscCall(MatDestroy(&D));

    168:   PetscCall(MatAssemblyBegin(G, MAT_FINAL_ASSEMBLY));
    169:   PetscCall(MatAssemblyEnd(G, MAT_FINAL_ASSEMBLY));
    170:   PetscCall(MatViewFromOptions(G, NULL, "-G_view"));
    171:   PetscCall(MatDestroy(&G));
    172:   PetscCall(PetscFinalize());
    173:   return 0;
    174: }

    176: /*TEST
    177:   test:
    178:     suffix: 0
    179:     args: -mat_type aij -G_view

    181:   test:
    182:     suffix: 1
    183:     args: -mat_type nest -G_view -mat_view_nest_sub

    185:   test:
    186:     suffix: 2
    187:     nsize: 2
    188:     args: -mat_type aij -G_view

    190:   test:
    191:     suffix: 3
    192:     nsize: 2
    193:     args: -mat_type nest -G_view
    194: TEST*/