Actual source code: space.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

      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: .keywords: PetscSpace, register
     40: .seealso: PetscSpaceRegisterAll(), PetscSpaceRegisterDestroy()

     42: @*/
     43: PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace))
     44: {

     48:   PetscFunctionListAdd(&PetscSpaceList, sname, function);
     49:   return(0);
     50: }

     52: /*@C
     53:   PetscSpaceSetType - Builds a particular PetscSpace

     55:   Collective on PetscSpace

     57:   Input Parameters:
     58: + sp   - The PetscSpace object
     59: - name - The kind of space

     61:   Options Database Key:
     62: . -petscspace_type <type> - Sets the PetscSpace type; use -help for a list of available types

     64:   Level: intermediate

     66: .keywords: PetscSpace, set, type
     67: .seealso: PetscSpaceGetType(), PetscSpaceCreate()
     68: @*/
     69: PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name)
     70: {
     71:   PetscErrorCode (*r)(PetscSpace);
     72:   PetscBool      match;

     77:   PetscObjectTypeCompare((PetscObject) sp, name, &match);
     78:   if (match) return(0);

     80:   PetscSpaceRegisterAll();
     81:   PetscFunctionListFind(PetscSpaceList, name, &r);
     82:   if (!r) SETERRQ1(PetscObjectComm((PetscObject) sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name);

     84:   if (sp->ops->destroy) {
     85:     (*sp->ops->destroy)(sp);
     86:     sp->ops->destroy = NULL;
     87:   }
     88:   sp->dim = PETSC_DETERMINE;
     89:   (*r)(sp);
     90:   PetscObjectChangeTypeName((PetscObject) sp, name);
     91:   return(0);
     92: }

     94: /*@C
     95:   PetscSpaceGetType - Gets the PetscSpace type name (as a string) from the object.

     97:   Not Collective

     99:   Input Parameter:
    100: . sp  - The PetscSpace

    102:   Output Parameter:
    103: . name - The PetscSpace type name

    105:   Level: intermediate

    107: .keywords: PetscSpace, get, type, name
    108: .seealso: PetscSpaceSetType(), PetscSpaceCreate()
    109: @*/
    110: PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name)
    111: {

    117:   if (!PetscSpaceRegisterAllCalled) {
    118:     PetscSpaceRegisterAll();
    119:   }
    120:   *name = ((PetscObject) sp)->type_name;
    121:   return(0);
    122: }

    124: /*@C
    125:   PetscSpaceView - Views a PetscSpace

    127:   Collective on PetscSpace

    129:   Input Parameter:
    130: + sp - the PetscSpace object to view
    131: - v  - the viewer

    133:   Level: developer

    135: .seealso PetscSpaceDestroy()
    136: @*/
    137: PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
    138: {
    139:   PetscBool      iascii;

    145:   if (!v) {PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) sp), &v);}
    146:   PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);
    147:   if (iascii) {
    148:     PetscObjectPrintClassNamePrefixType((PetscObject)sp,v);
    149:     PetscViewerASCIIPushTab(v);
    150:     PetscViewerASCIIPrintf(v, "Space in %D variables of order %D with %D components\n", sp->Nv, sp->degree, sp->Nc);
    151:     PetscViewerASCIIPopTab(v);
    152:   }
    153:   PetscViewerASCIIPushTab(v);
    154:   if (sp->ops->view) {(*sp->ops->view)(sp, v);}
    155:   PetscViewerASCIIPopTab(v);
    156:   return(0);
    157: }

    159: /*@
    160:   PetscSpaceSetFromOptions - sets parameters in a PetscSpace from the options database

    162:   Collective on PetscSpace

    164:   Input Parameter:
    165: . sp - the PetscSpace object to set options for

    167:   Options Database:
    168: . -petscspace_degree the approximation order of the space

    170:   Level: developer

    172: .seealso PetscSpaceView()
    173: @*/
    174: PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
    175: {
    176:   const char    *defaultType;
    177:   char           name[256];
    178:   PetscBool      flg, orderflg;

    183:   if (!((PetscObject) sp)->type_name) {
    184:     defaultType = PETSCSPACEPOLYNOMIAL;
    185:   } else {
    186:     defaultType = ((PetscObject) sp)->type_name;
    187:   }
    188:   if (!PetscSpaceRegisterAllCalled) {PetscSpaceRegisterAll();}

    190:   PetscObjectOptionsBegin((PetscObject) sp);
    191:   PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg);
    192:   if (flg) {
    193:     PetscSpaceSetType(sp, name);
    194:   } else if (!((PetscObject) sp)->type_name) {
    195:     PetscSpaceSetType(sp, defaultType);
    196:   }
    197:   {
    198:     PetscOptionsInt("-petscspace_order", "DEPRECATED: The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, &orderflg);
    199:     if (orderflg) {
    200:       int compare;

    202:       MPI_Comm_compare(PetscObjectComm((PetscObject)sp), PETSC_COMM_WORLD, &compare);

    204:       if (compare == MPI_IDENT || compare == MPI_CONGRUENT) {
    205:         PetscPrintf(PetscObjectComm((PetscObject)sp), "Warning: -petscspace_order is deprecated.  Use -petscspace_degree\n");
    206:       }
    207:     }
    208:   }
    209:   PetscOptionsInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL);
    210:   PetscOptionsInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL);
    211:   PetscOptionsInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL);
    212:   if (sp->ops->setfromoptions) {
    213:     (*sp->ops->setfromoptions)(PetscOptionsObject,sp);
    214:   }
    215:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
    216:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) sp);
    217:   PetscOptionsEnd();
    218:   PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view");
    219:   return(0);
    220: }

    222: /*@C
    223:   PetscSpaceSetUp - Construct data structures for the PetscSpace

    225:   Collective on PetscSpace

    227:   Input Parameter:
    228: . sp - the PetscSpace object to setup

    230:   Level: developer

    232: .seealso PetscSpaceView(), PetscSpaceDestroy()
    233: @*/
    234: PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
    235: {

    240:   if (sp->ops->setup) {(*sp->ops->setup)(sp);}
    241:   return(0);
    242: }

    244: /*@
    245:   PetscSpaceDestroy - Destroys a PetscSpace object

    247:   Collective on PetscSpace

    249:   Input Parameter:
    250: . sp - the PetscSpace object to destroy

    252:   Level: developer

    254: .seealso PetscSpaceView()
    255: @*/
    256: PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
    257: {

    261:   if (!*sp) return(0);

    264:   if (--((PetscObject)(*sp))->refct > 0) {*sp = 0; return(0);}
    265:   ((PetscObject) (*sp))->refct = 0;
    266:   DMDestroy(&(*sp)->dm);

    268:   (*(*sp)->ops->destroy)(*sp);
    269:   PetscHeaderDestroy(sp);
    270:   return(0);
    271: }

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

    276:   Collective on MPI_Comm

    278:   Input Parameter:
    279: . comm - The communicator for the PetscSpace object

    281:   Output Parameter:
    282: . sp - The PetscSpace object

    284:   Level: beginner

    286: .seealso: PetscSpaceSetType(), PETSCSPACEPOLYNOMIAL
    287: @*/
    288: PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp)
    289: {
    290:   PetscSpace     s;

    295:   PetscCitationsRegister(FECitation,&FEcite);
    296:   *sp  = NULL;
    297:   PetscFEInitializePackage();

    299:   PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView);

    301:   s->degree    = 0;
    302:   s->maxDegree = PETSC_DETERMINE;
    303:   s->Nc        = 1;
    304:   s->Nv        = 0;
    305:   s->dim       = PETSC_DETERMINE;
    306:   DMShellCreate(comm, &s->dm);
    307:   PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL);

    309:   *sp = s;
    310:   return(0);
    311: }

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

    316:   Input Parameter:
    317: . sp - The PetscSpace

    319:   Output Parameter:
    320: . dim - The dimension

    322:   Level: intermediate

    324: .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
    325: @*/
    326: PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
    327: {

    333:   if (sp->dim == PETSC_DETERMINE) {
    334:     if (sp->ops->getdimension) {(*sp->ops->getdimension)(sp, &sp->dim);}
    335:   }
    336:   *dim = sp->dim;
    337:   return(0);
    338: }

    340: /*@
    341:   PetscSpaceGetDegree - Return the polynomial degrees that characterize this space

    343:   Input Parameter:
    344: . sp - The PetscSpace

    346:   Output Parameter:
    347: + minDegree - The degree of the largest polynomial space contained in the space
    348: - maxDegree - The degree of the smallest polynomial space containing the space

    351:   Level: intermediate

    353: .seealso: PetscSpaceSetDegree(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
    354: @*/
    355: PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree)
    356: {
    361:   if (minDegree) *minDegree = sp->degree;
    362:   if (maxDegree) *maxDegree = sp->maxDegree;
    363:   return(0);
    364: }

    366: /*@
    367:   PetscSpaceSetDegree - Set the degree of approximation for this space.

    369:   Input Parameters:
    370: + sp - The PetscSpace
    371: . degree - The degree of the largest polynomial space contained in the space
    372: - maxDegree - The degree of the largest polynomial space containing the space.  One of degree and maxDegree can be PETSC_DETERMINE.

    374:   Level: intermediate

    376: .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
    377: @*/
    378: PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree)
    379: {
    382:   sp->degree = degree;
    383:   sp->maxDegree = maxDegree;
    384:   return(0);
    385: }

    387: /*@
    388:   PetscSpaceGetNumComponents - Return the number of components for this space

    390:   Input Parameter:
    391: . sp - The PetscSpace

    393:   Output Parameter:
    394: . Nc - The number of components

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

    398:   Level: intermediate

    400: .seealso: PetscSpaceSetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
    401: @*/
    402: PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
    403: {
    407:   *Nc = sp->Nc;
    408:   return(0);
    409: }

    411: /*@
    412:   PetscSpaceSetNumComponents - Set the number of components for this space

    414:   Input Parameters:
    415: + sp - The PetscSpace
    416: - order - The number of components

    418:   Level: intermediate

    420: .seealso: PetscSpaceGetNumComponents(), PetscSpaceCreate(), PetscSpace
    421: @*/
    422: PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
    423: {
    426:   sp->Nc = Nc;
    427:   return(0);
    428: }

    430: PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
    431: {
    434:   sp->Nv = n;
    435:   return(0);
    436: }

    438: PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
    439: {
    443:   *n = sp->Nv;
    444:   return(0);
    445: }

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

    451:   Input Parameters:
    452: + sp      - The PetscSpace
    453: . npoints - The number of evaluation points, in reference coordinates
    454: - points  - The point coordinates

    456:   Output Parameters:
    457: + B - The function evaluations in a npoints x nfuncs array
    458: . D - The derivative evaluations in a npoints x nfuncs x dim array
    459: - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array

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

    464:   Level: advanced

    466: .seealso: PetscFEGetTabulation(), PetscFEGetDefaultTabulation(), PetscSpaceCreate()
    467: @*/
    468: PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[])
    469: {

    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: {

    512:   *subsp = NULL;
    513:   if (sp->ops->getheightsubspace) {
    514:     (*sp->ops->getheightsubspace)(sp, height, subsp);
    515:   }
    516:   return(0);
    517: }