Date: 2026-06-01T23:13:18+00:00

Actual source code: space.c

      1: #include <petsc/private/petscfeimpl.h>
      2: #include <petscdmshell.h>

      4: PetscClassId PETSCSPACE_CLASSID = 0;

      6: PetscFunctionList PetscSpaceList              = NULL;
      7: PetscBool         PetscSpaceRegisterAllCalled = PETSC_FALSE;

      9: /*@C
     10:   PetscSpaceRegister - Adds a new `PetscSpace` implementation

     12:   Not Collective, No Fortran Support

     14:   Input Parameters:
     15: + sname    - The name of a new user-defined creation routine
     16: - function - The creation routine for the implementation type

     18:   Example Usage:
     19: .vb
     20:     PetscSpaceRegister("my_space", MyPetscSpaceCreate);
     21: .ve

     23:   Then, your PetscSpace type can be chosen with the procedural interface via
     24: .vb
     25:     PetscSpaceCreate(MPI_Comm, PetscSpace *);
     26:     PetscSpaceSetType(PetscSpace, "my_space");
     27: .ve
     28:   or at runtime via the option
     29: .vb
     30:     -petscspace_type my_space
     31: .ve

     33:   Level: advanced

     35:   Note:
     36:   `PetscSpaceRegister()` may be called multiple times to add several user-defined types of `PetscSpace`.  The creation function is called
     37:   when the type is set to 'name'.

     39: .seealso: `PetscSpace`, `PetscSpaceRegisterAll()`, `PetscSpaceRegisterDestroy()`
     40: @*/
     41: PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace))
     42: {
     43:   PetscFunctionBegin;
     44:   PetscCall(PetscFunctionListAdd(&PetscSpaceList, sname, function));
     45:   PetscFunctionReturn(PETSC_SUCCESS);
     46: }

     48: /*@
     49:   PetscSpaceSetType - Builds a particular `PetscSpace`

     51:   Collective

     53:   Input Parameters:
     54: + sp   - The `PetscSpace` object
     55: - name - The kind of space

     57:   Options Database Key:
     58: . -petscspace_type type - Sets the `PetscSpace` type; use -help for a list of available types

     60:   Level: intermediate

     62: .seealso: `PetscSpace`, `PetscSpaceType`, `PetscSpaceGetType()`, `PetscSpaceCreate()`
     63: @*/
     64: PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name)
     65: {
     66:   PetscErrorCode (*r)(PetscSpace);
     67:   PetscBool match;

     69:   PetscFunctionBegin;
     71:   PetscCall(PetscObjectTypeCompare((PetscObject)sp, name, &match));
     72:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

     74:   PetscCall(PetscSpaceRegisterAll());
     75:   PetscCall(PetscFunctionListFind(PetscSpaceList, name, &r));
     76:   PetscCheck(r, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name);

     78:   PetscTryTypeMethod(sp, destroy);
     79:   sp->ops->destroy = NULL;

     81:   sp->dim = PETSC_DETERMINE;
     82:   PetscCall((*r)(sp));
     83:   PetscCall(PetscObjectChangeTypeName((PetscObject)sp, name));
     84:   PetscFunctionReturn(PETSC_SUCCESS);
     85: }

     87: /*@
     88:   PetscSpaceGetType - Gets the `PetscSpaceType` (as a string) from the object.

     90:   Not Collective

     92:   Input Parameter:
     93: . sp - The `PetscSpace`

     95:   Output Parameter:
     96: . name - The `PetscSpace` type name

     98:   Level: intermediate

    100: .seealso: `PetscSpaceType`, `PetscSpace`, `PetscSpaceSetType()`, `PetscSpaceCreate()`
    101: @*/
    102: PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name)
    103: {
    104:   PetscFunctionBegin;
    106:   PetscAssertPointer(name, 2);
    107:   if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll());
    108:   *name = ((PetscObject)sp)->type_name;
    109:   PetscFunctionReturn(PETSC_SUCCESS);
    110: }

    112: /*@
    113:   PetscSpaceViewFromOptions - View a `PetscSpace` based on values in the options database

    115:   Collective

    117:   Input Parameters:
    118: + A    - the `PetscSpace` object
    119: . obj  - Optional object that provides the options name prefix
    120: - name - command line option name

    122:   Options Database Key:
    123: . -name [viewertype][:...] - option name and values. See `PetscObjectViewFromOptions()` for the possible arguments

    125:   Level: intermediate

    127: .seealso: `PetscSpace`, `PetscSpaceView()`, `PetscObjectViewFromOptions()`, `PetscSpaceCreate()`
    128: @*/
    129: PetscErrorCode PetscSpaceViewFromOptions(PetscSpace A, PetscObject obj, const char name[])
    130: {
    131:   PetscFunctionBegin;
    133:   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
    134:   PetscFunctionReturn(PETSC_SUCCESS);
    135: }

    137: /*@
    138:   PetscSpaceView - Views a `PetscSpace`

    140:   Collective

    142:   Input Parameters:
    143: + sp - the `PetscSpace` object to view
    144: - v  - the viewer

    146:   Level: beginner

    148: .seealso: `PetscSpace`, `PetscViewer`, `PetscSpaceViewFromOptions()`, `PetscSpaceDestroy()`
    149: @*/
    150: PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
    151: {
    152:   PetscInt  pdim;
    153:   PetscBool isascii;

    155:   PetscFunctionBegin;
    158:   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)sp), &v));
    159:   PetscCall(PetscSpaceGetDimension(sp, &pdim));
    160:   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)sp, v));
    161:   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &isascii));
    162:   PetscCall(PetscViewerASCIIPushTab(v));
    163:   if (isascii) PetscCall(PetscViewerASCIIPrintf(v, "Space in %" PetscInt_FMT " variables with %" PetscInt_FMT " components, size %" PetscInt_FMT "\n", sp->Nv, sp->Nc, pdim));
    164:   PetscTryTypeMethod(sp, view, v);
    165:   PetscCall(PetscViewerASCIIPopTab(v));
    166:   PetscFunctionReturn(PETSC_SUCCESS);
    167: }

    169: /*@
    170:   PetscSpaceSetFromOptions - sets parameters in a `PetscSpace` from the options database

    172:   Collective

    174:   Input Parameter:
    175: . sp - the `PetscSpace` object to set options for

    177:   Options Database Keys:
    178: + -petscspace_degree deg   - the degree of the space
    179: . -petscspace_variables n  - the number of different variables, e.g. x and y
    180: - -petscspace_components c - the number of components, say d for a vector field

    182:   Level: intermediate

    184: .seealso: `PetscSpace`, `PetscSpaceView()`
    185: @*/
    186: PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
    187: {
    188:   const char *defaultType;
    189:   char        name[256];
    190:   PetscBool   flg;

    192:   PetscFunctionBegin;
    194:   if (!((PetscObject)sp)->type_name) defaultType = PETSCSPACEPOLYNOMIAL;
    195:   else defaultType = ((PetscObject)sp)->type_name;
    196:   if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll());

    198:   PetscObjectOptionsBegin((PetscObject)sp);
    199:   PetscCall(PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg));
    200:   if (flg) PetscCall(PetscSpaceSetType(sp, name));
    201:   else if (!((PetscObject)sp)->type_name) PetscCall(PetscSpaceSetType(sp, defaultType));
    202:   {
    203:     PetscCall(PetscOptionsDeprecated("-petscspace_order", "-petscspace_degree", "3.11", NULL));
    204:   }
    205:   PetscCall(PetscOptionsBoundedInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL, 0));
    206:   PetscCall(PetscOptionsBoundedInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL, 0));
    207:   PetscCall(PetscOptionsBoundedInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL, -1));
    208:   PetscTryTypeMethod(sp, setfromoptions, PetscOptionsObject);
    209:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
    210:   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)sp, PetscOptionsObject));
    211:   PetscOptionsEnd();
    212:   PetscCall(PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view"));
    213:   PetscFunctionReturn(PETSC_SUCCESS);
    214: }

    216: /*@
    217:   PetscSpaceSetUp - Construct data structures for the `PetscSpace`

    219:   Collective

    221:   Input Parameter:
    222: . sp - the `PetscSpace` object to setup

    224:   Level: intermediate

    226: .seealso: `PetscSpace`, `PetscSpaceView()`, `PetscSpaceDestroy()`
    227: @*/
    228: PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
    229: {
    230:   PetscFunctionBegin;
    232:   PetscTryTypeMethod(sp, setup);
    233:   PetscFunctionReturn(PETSC_SUCCESS);
    234: }

    236: /*@
    237:   PetscSpaceDestroy - Destroys a `PetscSpace` object

    239:   Collective

    241:   Input Parameter:
    242: . sp - the `PetscSpace` object to destroy

    244:   Level: beginner

    246: .seealso: `PetscSpace`, `PetscSpaceCreate()`
    247: @*/
    248: PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
    249: {
    250:   PetscFunctionBegin;
    251:   if (!*sp) PetscFunctionReturn(PETSC_SUCCESS);

    254:   if (--((PetscObject)*sp)->refct > 0) {
    255:     *sp = NULL;
    256:     PetscFunctionReturn(PETSC_SUCCESS);
    257:   }
    258:   ((PetscObject)*sp)->refct = 0;
    259:   PetscCall(DMDestroy(&(*sp)->dm));

    261:   PetscUseTypeMethod(*sp, destroy);
    262:   PetscCall(PetscHeaderDestroy(sp));
    263:   PetscFunctionReturn(PETSC_SUCCESS);
    264: }

    266: /*@
    267:   PetscSpaceCreate - Creates an empty `PetscSpace` object. The type can then be set with `PetscSpaceSetType()`.

    269:   Collective

    271:   Input Parameter:
    272: . comm - The communicator for the `PetscSpace` object

    274:   Output Parameter:
    275: . sp - The `PetscSpace` object

    277:   Level: beginner

    279: .seealso: `PetscSpace`, `PetscSpaceSetType()`, `PETSCSPACEPOLYNOMIAL`
    280: @*/
    281: PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp)
    282: {
    283:   PetscSpace s;

    285:   PetscFunctionBegin;
    286:   PetscAssertPointer(sp, 2);
    287:   PetscCall(PetscCitationsRegister(FECitation, &FEcite));
    288:   PetscCall(PetscFEInitializePackage());

    290:   PetscCall(PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView));
    291:   s->degree    = 0;
    292:   s->maxDegree = PETSC_DETERMINE;
    293:   s->Nc        = 1;
    294:   s->Nv        = 0;
    295:   s->dim       = PETSC_DETERMINE;
    296:   PetscCall(DMShellCreate(comm, &s->dm));
    297:   PetscCall(PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL));

    299:   *sp = s;
    300:   PetscFunctionReturn(PETSC_SUCCESS);
    301: }

    303: /*@
    304:   PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors

    306:   Input Parameter:
    307: . sp - The `PetscSpace`

    309:   Output Parameter:
    310: . dim - The dimension

    312:   Level: intermediate

    314: .seealso: `PetscSpace`, `PetscSpaceGetDegree()`, `PetscSpaceCreate()`
    315: @*/
    316: PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
    317: {
    318:   PetscFunctionBegin;
    320:   PetscAssertPointer(dim, 2);
    321:   if (sp->dim == PETSC_DETERMINE) PetscTryTypeMethod(sp, getdimension, &sp->dim);
    322:   *dim = sp->dim;
    323:   PetscFunctionReturn(PETSC_SUCCESS);
    324: }

    326: /*@
    327:   PetscSpaceGetDegree - Return the polynomial degrees that characterize this space

    329:   Input Parameter:
    330: . sp - The `PetscSpace`

    332:   Output Parameters:
    333: + minDegree - The degree of the largest polynomial space contained in the space, pass `NULL` if not needed
    334: - maxDegree - The degree of the smallest polynomial space containing the space, pass `NULL` if not needed

    336:   Level: intermediate

    338: .seealso: `PetscSpace`, `PetscSpaceSetDegree()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
    339: @*/
    340: PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PeOp PetscInt *minDegree, PeOp PetscInt *maxDegree)
    341: {
    342:   PetscFunctionBegin;
    344:   if (minDegree) PetscAssertPointer(minDegree, 2);
    345:   if (maxDegree) PetscAssertPointer(maxDegree, 3);
    346:   if (minDegree) *minDegree = sp->degree;
    347:   if (maxDegree) *maxDegree = sp->maxDegree;
    348:   PetscFunctionReturn(PETSC_SUCCESS);
    349: }

    351: /*@
    352:   PetscSpaceSetDegree - Set the degree of approximation for this space.

    354:   Input Parameters:
    355: + sp        - The `PetscSpace`
    356: . degree    - The degree of the largest polynomial space contained in the space
    357: - maxDegree - The degree of the largest polynomial space containing the space.  One of degree and maxDegree can be `PETSC_DETERMINE`.

    359:   Level: intermediate

    361: .seealso: `PetscSpace`, `PetscSpaceGetDegree()`, `PetscSpaceCreate()`
    362: @*/
    363: PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree)
    364: {
    365:   PetscFunctionBegin;
    367:   sp->degree    = degree;
    368:   sp->maxDegree = maxDegree;
    369:   PetscFunctionReturn(PETSC_SUCCESS);
    370: }

    372: /*@
    373:   PetscSpaceGetNumComponents - Return the number of components for this space

    375:   Input Parameter:
    376: . sp - The `PetscSpace`

    378:   Output Parameter:
    379: . Nc - The number of components

    381:   Level: intermediate

    383:   Note:
    384:   A vector space, for example, will have d components, where d is the spatial dimension

    386: .seealso: `PetscSpace`, `PetscSpaceSetNumComponents()`, `PetscSpaceGetNumVariables()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
    387: @*/
    388: PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
    389: {
    390:   PetscFunctionBegin;
    392:   PetscAssertPointer(Nc, 2);
    393:   *Nc = sp->Nc;
    394:   PetscFunctionReturn(PETSC_SUCCESS);
    395: }

    397: /*@
    398:   PetscSpaceSetNumComponents - Set the number of components for this space

    400:   Input Parameters:
    401: + sp - The `PetscSpace`
    402: - Nc - The number of components

    404:   Level: intermediate

    406: .seealso: `PetscSpace`, `PetscSpaceGetNumComponents()`, `PetscSpaceSetNumVariables()`, `PetscSpaceCreate()`
    407: @*/
    408: PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
    409: {
    410:   PetscFunctionBegin;
    412:   sp->Nc = Nc;
    413:   PetscFunctionReturn(PETSC_SUCCESS);
    414: }

    416: /*@
    417:   PetscSpaceSetNumVariables - Set the number of variables for this space

    419:   Input Parameters:
    420: + sp - The `PetscSpace`
    421: - n  - The number of variables, e.g. x, y, z...

    423:   Level: intermediate

    425: .seealso: `PetscSpace`, `PetscSpaceGetNumVariables()`, `PetscSpaceSetNumComponents()`, `PetscSpaceCreate()`
    426: @*/
    427: PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
    428: {
    429:   PetscFunctionBegin;
    431:   sp->Nv = n;
    432:   PetscFunctionReturn(PETSC_SUCCESS);
    433: }

    435: /*@
    436:   PetscSpaceGetNumVariables - Return the number of variables for this space

    438:   Input Parameter:
    439: . sp - The `PetscSpace`

    441:   Output Parameter:
    442: . n - The number of variables, e.g. x, y, z...

    444:   Level: intermediate

    446: .seealso: `PetscSpace`, `PetscSpaceSetNumVariables()`, `PetscSpaceGetNumComponents()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
    447: @*/
    448: PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
    449: {
    450:   PetscFunctionBegin;
    452:   PetscAssertPointer(n, 2);
    453:   *n = sp->Nv;
    454:   PetscFunctionReturn(PETSC_SUCCESS);
    455: }

    457: /*@
    458:   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point

    460:   Input Parameters:
    461: + sp      - The `PetscSpace`
    462: . npoints - The number of evaluation points, in reference coordinates
    463: - points  - The point coordinates

    465:   Output Parameters:
    466: + B - The function evaluations in a `npoints` x `nfuncs` array
    467: . D - The derivative evaluations in a `npoints` x `nfuncs` x `dim` array
    468: - H - The second derivative evaluations in a `npoints` x `nfuncs` x `dim` x `dim` array

    470:   Level: beginner

    472:   Note:
    473:   Above `nfuncs` is the dimension of the space, and `dim` is the spatial dimension. The coordinates are given
    474:   on the reference cell, not in real space.

    476: .seealso: `PetscSpace`, `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()`, `PetscSpaceCreate()`
    477: @*/
    478: PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PeOp PetscReal B[], PeOp PetscReal D[], PeOp PetscReal H[])
    479: {
    480:   PetscFunctionBegin;
    481:   if (!npoints) PetscFunctionReturn(PETSC_SUCCESS);
    483:   if (sp->Nv) PetscAssertPointer(points, 3);
    484:   if (B) PetscAssertPointer(B, 4);
    485:   if (D) PetscAssertPointer(D, 5);
    486:   if (H) PetscAssertPointer(H, 6);
    487:   PetscTryTypeMethod(sp, evaluate, npoints, points, B, D, H);
    488:   PetscFunctionReturn(PETSC_SUCCESS);
    489: }

    491: /*@
    492:   PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.

    494:   Not Collective

    496:   Input Parameters:
    497: + sp     - the `PetscSpace` object
    498: - height - the height of the mesh point for which the subspace is desired

    500:   Output Parameter:
    501: . subsp - the subspace

    503:   Level: advanced

    505:   Notes:
    506:   If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and
    507:   pointwise values are not defined on the element boundaries), or if the implementation of `PetscSpace` does not
    508:   support extracting subspaces, then NULL is returned.

    510:   This does not increment the reference count on the returned space, and the user should not destroy it.

    512: .seealso: `PetscDualSpaceGetHeightSubspace()`, `PetscSpace`
    513: @*/
    514: PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
    515: {
    516:   PetscFunctionBegin;
    518:   PetscAssertPointer(subsp, 3);
    519:   *subsp = NULL;
    520:   PetscTryTypeMethod(sp, getheightsubspace, height, subsp);
    521:   PetscFunctionReturn(PETSC_SUCCESS);
    522: }