Date: 2022-08-02T03:14:28+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

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

     18:   Notes:
     19:   PetscSpaceRegister() may be called multiple times to add several user-defined types of PetscSpaces.  The creation function is called
     20:   when the type is set to 'name'.

     22:   Sample usage:
     23: .vb
     24:     PetscSpaceRegister("my_space", MyPetscSpaceCreate);
     25: .ve

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

     37:   Level: advanced

     39: .seealso: PetscSpaceRegisterAll(), PetscSpaceRegisterDestroy()

     41: @*/
     42: PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace))
     43: {
     44:   PetscFunctionListAdd(&PetscSpaceList, sname, function);
     45:   return 0;
     46: }

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

     51:   Collective on sp

     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: PetscSpaceGetType(), PetscSpaceCreate()
     63: @*/
     64: PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name)
     65: {
     66:   PetscErrorCode (*r)(PetscSpace);
     67:   PetscBool      match;

     70:   PetscObjectTypeCompare((PetscObject) sp, name, &match);
     71:   if (match) return 0;

     73:   PetscSpaceRegisterAll();
     74:   PetscFunctionListFind(PetscSpaceList, name, &r);

     77:   if (sp->ops->destroy) {
     78:     (*sp->ops->destroy)(sp);
     79:     sp->ops->destroy = NULL;
     80:   }
     81:   sp->dim = PETSC_DETERMINE;
     82:   (*r)(sp);
     83:   PetscObjectChangeTypeName((PetscObject) sp, name);
     84:   return 0;
     85: }

     87: /*@C
     88:   PetscSpaceGetType - Gets the PetscSpace type name (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: PetscSpaceSetType(), PetscSpaceCreate()
    101: @*/
    102: PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name)
    103: {
    106:   if (!PetscSpaceRegisterAllCalled) {
    107:     PetscSpaceRegisterAll();
    108:   }
    109:   *name = ((PetscObject) sp)->type_name;
    110:   return 0;
    111: }

    113: /*@C
    114:    PetscSpaceViewFromOptions - View from Options

    116:    Collective on PetscSpace

    118:    Input Parameters:
    119: +  A - the PetscSpace object
    120: .  obj - Optional object
    121: -  name - command line option

    123:    Level: intermediate
    124: .seealso:  PetscSpace, PetscSpaceView, PetscObjectViewFromOptions(), PetscSpaceCreate()
    125: @*/
    126: PetscErrorCode  PetscSpaceViewFromOptions(PetscSpace A,PetscObject obj,const char name[])
    127: {
    129:   PetscObjectViewFromOptions((PetscObject)A,obj,name);
    130:   return 0;
    131: }

    133: /*@C
    134:   PetscSpaceView - Views a PetscSpace

    136:   Collective on sp

    138:   Input Parameters:
    139: + sp - the PetscSpace object to view
    140: - v  - the viewer

    142:   Level: beginner

    144: .seealso PetscSpaceDestroy()
    145: @*/
    146: PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
    147: {
    148:   PetscInt       pdim;
    149:   PetscBool      iascii;

    153:   if (!v) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) sp), &v);
    154:   PetscSpaceGetDimension(sp, &pdim);
    155:   PetscObjectPrintClassNamePrefixType((PetscObject)sp,v);
    156:   PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);
    157:   PetscViewerASCIIPushTab(v);
    158:   if (iascii) PetscViewerASCIIPrintf(v, "Space in %D variables with %D components, size %D\n", sp->Nv, sp->Nc, pdim);
    159:   if (sp->ops->view) (*sp->ops->view)(sp, v);
    160:   PetscViewerASCIIPopTab(v);
    161:   return 0;
    162: }

    164: /*@
    165:   PetscSpaceSetFromOptions - sets parameters in a PetscSpace from the options database

    167:   Collective on sp

    169:   Input Parameter:
    170: . sp - the PetscSpace object to set options for

    172:   Options Database:
    173: + -petscspace_degree <deg> - the approximation order of the space
    174: . -petscspace_variables <n> - the number of different variables, e.g. x and y
    175: - -petscspace_components <c> - the number of components, say d for a vector field

    177:   Level: intermediate

    179: .seealso PetscSpaceView()
    180: @*/
    181: PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
    182: {
    183:   const char    *defaultType;
    184:   char           name[256];
    185:   PetscBool      flg;

    189:   if (!((PetscObject) sp)->type_name) {
    190:     defaultType = PETSCSPACEPOLYNOMIAL;
    191:   } else {
    192:     defaultType = ((PetscObject) sp)->type_name;
    193:   }
    194:   if (!PetscSpaceRegisterAllCalled) PetscSpaceRegisterAll();

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

    220: /*@C
    221:   PetscSpaceSetUp - Construct data structures for the PetscSpace

    223:   Collective on sp

    225:   Input Parameter:
    226: . sp - the PetscSpace object to setup

    228:   Level: intermediate

    230: .seealso PetscSpaceView(), PetscSpaceDestroy()
    231: @*/
    232: PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
    233: {
    235:   if (sp->ops->setup) (*sp->ops->setup)(sp);
    236:   return 0;
    237: }

    239: /*@
    240:   PetscSpaceDestroy - Destroys a PetscSpace object

    242:   Collective on sp

    244:   Input Parameter:
    245: . sp - the PetscSpace object to destroy

    247:   Level: beginner

    249: .seealso PetscSpaceView()
    250: @*/
    251: PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
    252: {
    253:   if (!*sp) return 0;

    256:   if (--((PetscObject)(*sp))->refct > 0) {*sp = NULL; return 0;}
    257:   ((PetscObject) (*sp))->refct = 0;
    258:   DMDestroy(&(*sp)->dm);

    260:   (*(*sp)->ops->destroy)(*sp);
    261:   PetscHeaderDestroy(sp);
    262:   return 0;
    263: }

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

    268:   Collective

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

    273:   Output Parameter:
    274: . sp - The PetscSpace object

    276:   Level: beginner

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

    285:   PetscCitationsRegister(FECitation,&FEcite);
    286:   *sp  = NULL;
    287:   PetscFEInitializePackage();

    289:   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:   DMShellCreate(comm, &s->dm);
    297:   PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL);

    299:   *sp = s;
    300:   return 0;
    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: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
    315: @*/
    316: PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
    317: {
    320:   if (sp->dim == PETSC_DETERMINE) {
    321:     if (sp->ops->getdimension) (*sp->ops->getdimension)(sp, &sp->dim);
    322:   }
    323:   *dim = sp->dim;
    324:   return 0;
    325: }

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

    330:   Input Parameter:
    331: . sp - The PetscSpace

    333:   Output Parameters:
    334: + minDegree - The degree of the largest polynomial space contained in the space
    335: - maxDegree - The degree of the smallest polynomial space containing the space

    337:   Level: intermediate

    339: .seealso: PetscSpaceSetDegree(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
    340: @*/
    341: PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree)
    342: {
    346:   if (minDegree) *minDegree = sp->degree;
    347:   if (maxDegree) *maxDegree = sp->maxDegree;
    348:   return 0;
    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: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
    362: @*/
    363: PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree)
    364: {
    366:   sp->degree = degree;
    367:   sp->maxDegree = maxDegree;
    368:   return 0;
    369: }

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

    374:   Input Parameter:
    375: . sp - The PetscSpace

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

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

    382:   Level: intermediate

    384: .seealso: PetscSpaceSetNumComponents(), PetscSpaceGetNumVariables(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
    385: @*/
    386: PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
    387: {
    390:   *Nc = sp->Nc;
    391:   return 0;
    392: }

    394: /*@
    395:   PetscSpaceSetNumComponents - Set the number of components for this space

    397:   Input Parameters:
    398: + sp - The PetscSpace
    399: - order - The number of components

    401:   Level: intermediate

    403: .seealso: PetscSpaceGetNumComponents(), PetscSpaceSetNumVariables(), PetscSpaceCreate(), PetscSpace
    404: @*/
    405: PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
    406: {
    408:   sp->Nc = Nc;
    409:   return 0;
    410: }

    412: /*@
    413:   PetscSpaceSetNumVariables - Set the number of variables for this space

    415:   Input Parameters:
    416: + sp - The PetscSpace
    417: - n - The number of variables, e.g. x, y, z...

    419:   Level: intermediate

    421: .seealso: PetscSpaceGetNumVariables(), PetscSpaceSetNumComponents(), PetscSpaceCreate(), PetscSpace
    422: @*/
    423: PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
    424: {
    426:   sp->Nv = n;
    427:   return 0;
    428: }

    430: /*@
    431:   PetscSpaceGetNumVariables - Return the number of variables for this space

    433:   Input Parameter:
    434: . sp - The PetscSpace

    436:   Output Parameter:
    437: . Nc - The number of variables, e.g. x, y, z...

    439:   Level: intermediate

    441: .seealso: PetscSpaceSetNumVariables(), PetscSpaceGetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
    442: @*/
    443: PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
    444: {
    447:   *n = sp->Nv;
    448:   return 0;
    449: }

    451: /*@C
    452:   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point

    454:   Input Parameters:
    455: + sp      - The PetscSpace
    456: . npoints - The number of evaluation points, in reference coordinates
    457: - points  - The point coordinates

    459:   Output Parameters:
    460: + B - The function evaluations in a npoints x nfuncs array
    461: . D - The derivative evaluations in a npoints x nfuncs x dim array
    462: - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array

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

    467:   Level: beginner

    469: .seealso: PetscFECreateTabulation(), PetscFEGetCellTabulation(), PetscSpaceCreate()
    470: @*/
    471: PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[])
    472: {
    473:   if (!npoints) return 0;
    479:   if (sp->ops->evaluate) (*sp->ops->evaluate)(sp, npoints, points, B, D, H);
    480:   return 0;
    481: }

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

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

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

    492:   Not collective

    494:   Input Parameters:
    495: + sp - the PetscSpace object
    496: - height - the height of the mesh point for which the subspace is desired

    498:   Output Parameter:
    499: . subsp - the subspace

    501:   Level: advanced

    503: .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace
    504: @*/
    505: PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
    506: {
    509:   *subsp = NULL;
    510:   if (sp->ops->getheightsubspace) {
    511:     (*sp->ops->getheightsubspace)(sp, height, subsp);
    512:   }
    513:   return 0;
    514: }