xref: /petsc/doc/developers/objects.md (revision 2286efddd54511ab18e8e2adb1e023c4bf8f0b92)
14bcd95a3SBarry Smith# Basic Object Design and Implementation
24bcd95a3SBarry Smith
34bcd95a3SBarry SmithPETSc is designed by using strong data encapsulation. Hence, any
44bcd95a3SBarry Smithcollection of data (for instance, a sparse matrix) is stored in a way
54bcd95a3SBarry Smiththat is completely private from the application code. The application
64bcd95a3SBarry Smithcode can manipulate the data only through a well-defined interface,
74bcd95a3SBarry Smithsince it does *not* "know" how the data is stored internally.
84bcd95a3SBarry Smith
94bcd95a3SBarry Smith## Introduction
104bcd95a3SBarry Smith
114bcd95a3SBarry SmithPETSc is designed around several classes including `Vec` (vectors) and
124bcd95a3SBarry Smith`Mat` (matrices, both dense and sparse). Each class is implemented by
134bcd95a3SBarry Smithusing a C `struct` that contains the data and function pointers for
144bcd95a3SBarry Smithoperations on the data (much like virtual functions in C++ classes).
154bcd95a3SBarry SmithEach class consists of three parts:
164bcd95a3SBarry Smith
174bcd95a3SBarry SmithA (small) common part shared by all PETSc classes (for example, both
184bcd95a3SBarry Smith`KSP` and `PC` have this same header).
194bcd95a3SBarry Smith
204bcd95a3SBarry SmithAnother common part shared by all PETSc implementations of the class
214bcd95a3SBarry Smith(for example, both `KSPGMRES` and `KSPCG` have this common
224bcd95a3SBarry Smithsubheader).
234bcd95a3SBarry Smith
244bcd95a3SBarry SmithA private part used by only one particular implementation written in
254bcd95a3SBarry SmithPETSc.
264bcd95a3SBarry Smith
274bcd95a3SBarry SmithFor example, all matrix (`Mat`) classes share a function table of
284bcd95a3SBarry Smithoperations that may be performed on the matrix; all PETSc matrix
294bcd95a3SBarry Smithimplementations share some additional data fields, including matrix
304bcd95a3SBarry Smithparallel layout, while a particular matrix implementation in PETSc (say
314bcd95a3SBarry Smithcompressed sparse row) has its own data fields for storing the actual
324bcd95a3SBarry Smithmatrix values and sparsity pattern. This will be explained in more
334bcd95a3SBarry Smithdetail in the following sections. New class implementations *must* use
344bcd95a3SBarry Smiththe PETSc common part.
354bcd95a3SBarry Smith
364bcd95a3SBarry SmithWe will use `<class>_<implementation>` to denote the actual source code
374bcd95a3SBarry Smithand data structures used for a particular implementation of an object
384bcd95a3SBarry Smiththat has the `<class>` interface.
394bcd95a3SBarry Smith
404bcd95a3SBarry Smith## Organization of the Source Code
414bcd95a3SBarry Smith
424bcd95a3SBarry SmithEach class has the following organization.
434bcd95a3SBarry Smith
444bcd95a3SBarry SmithIts own, application-public, include file `include/petsc<class>.h`.
454bcd95a3SBarry Smith
464bcd95a3SBarry SmithIts own directory, `src/<class>` or `src/<package>/<class>`.
474bcd95a3SBarry Smith
484bcd95a3SBarry SmithA data structure defined in the file
494bcd95a3SBarry Smith`include/petsc/private/<class>impl.h`. This data structure is shared
504bcd95a3SBarry Smithby all the different PETSc implementations of the class. For example,
514bcd95a3SBarry Smithfor matrices it is shared by dense, sparse, parallel, and sequential
524bcd95a3SBarry Smithformats.
534bcd95a3SBarry Smith
544bcd95a3SBarry SmithAn abstract interface that defines the application-callable functions
554bcd95a3SBarry Smithfor the class. These are defined in the directory
564bcd95a3SBarry Smith`src/<class>/interface`. This is how polymorphism is supported with
574bcd95a3SBarry Smithcode that implements the abstract interface to the operations on the
584bcd95a3SBarry Smithobject. Essentially, these routines do some error checking of arguments
594bcd95a3SBarry Smithand logging of profiling information and then call the function
604bcd95a3SBarry Smithappropriate for the particular implementation of the object. The name of
614bcd95a3SBarry Smiththe abstract function is `<class>Operation`, for instance,
624bcd95a3SBarry Smith`MatMult()` or `PCCreate(`), while the name of a particular
634bcd95a3SBarry Smithimplementation is `<class>Operation_<implementation>`, for instance,
644bcd95a3SBarry Smith`MatMult_SeqAIJ()` or `PCCreate_ILU()`. These naming conventions are
654bcd95a3SBarry Smithused to simplify code maintenance (also see Section [sec:stylenames]).
664bcd95a3SBarry Smith
674bcd95a3SBarry SmithOne or more actual implementations of the class (for example, sparse
684bcd95a3SBarry Smithuniprocessor and parallel matrices implemented with the AIJ storage
694bcd95a3SBarry Smithformat). These are each in a subdirectory of `src/<class>/impls`.
704bcd95a3SBarry SmithExcept in rare circumstances, data structures defined here should not be
714bcd95a3SBarry Smithreferenced from outside this directory.
724bcd95a3SBarry Smith
734bcd95a3SBarry SmithEach type of object (for instance, a vector) is defined in its own
744bcd95a3SBarry Smithpublic include file, by `typedef _p_<class>* <class>`; (for example,
754bcd95a3SBarry Smith`typedef _p_Vec* Vec;`). This organization allows the compiler to
764bcd95a3SBarry Smithperform type checking on all subroutine calls while at the same time
774bcd95a3SBarry Smithcompletely removing the details of the implementation of `_p_<class>`
784bcd95a3SBarry Smithfrom the application code. This capability is extremely important
794bcd95a3SBarry Smithbecause it allows the library internals to be changed without altering
804bcd95a3SBarry Smithor recompiling the application code.
814bcd95a3SBarry Smith
824bcd95a3SBarry Smith## Common Object Header
834bcd95a3SBarry Smith
847f296bb3SBarry SmithAll PETSc objects (derived from the base class `PetscObject`) have the following common header structures
854bcd95a3SBarry Smithdefined in
864bcd95a3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/include/petsc/private/petscimpl.h.html">include/petsc/private/petscimpl.h</a>
874bcd95a3SBarry Smith
884bcd95a3SBarry Smith```
894bcd95a3SBarry Smithtypedef struct {
904bcd95a3SBarry Smith  PetscErrorCode (*view)(PetscObject, Viewer);
914bcd95a3SBarry Smith  PetscErrorCode (*destroy)(PetscObject);
924bcd95a3SBarry Smith} PetscOps;
934bcd95a3SBarry Smith```
944bcd95a3SBarry Smith
954bcd95a3SBarry Smith```
964bcd95a3SBarry Smithstruct _p_<class> {
974bcd95a3SBarry Smith  PetscClassId     classid;
984bcd95a3SBarry Smith  PetscOps         *bops;
994bcd95a3SBarry Smith  <class>Ops       *ops;
1004bcd95a3SBarry Smith  MPI_Comm         comm;
1014bcd95a3SBarry Smith  PetscLogDouble   flops,time,mem;
1024bcd95a3SBarry Smith  int              id;
1034bcd95a3SBarry Smith  int              refct;
1044bcd95a3SBarry Smith  int              tag;
1054bcd95a3SBarry Smith  DLList           qlist;
1064bcd95a3SBarry Smith  OList            olist;
1074bcd95a3SBarry Smith  char             *type_name;
1084bcd95a3SBarry Smith  PetscObject      parent;
1094bcd95a3SBarry Smith  char             *name;
1104bcd95a3SBarry Smith  char             *prefix;
1114bcd95a3SBarry Smith  void             *cpp;
1124bcd95a3SBarry Smith  void             **fortran_func_pointers;
1134bcd95a3SBarry Smith  ..........
1144bcd95a3SBarry Smith  CLASS-SPECIFIC DATASTRUCTURES
1154bcd95a3SBarry Smith};
1164bcd95a3SBarry Smith```
1174bcd95a3SBarry Smith
1184bcd95a3SBarry SmithHere `<class>ops` is a function table (like the `PetscOps` above)
1194bcd95a3SBarry Smiththat contains the function pointers for the operations specific to that
1204bcd95a3SBarry Smithclass. For example, the PETSc vector class object operations in
1214bcd95a3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/include/petsc/private/vecimpl.h.html">include/petsc/private/vecimpl.h</a>
1224bcd95a3SBarry Smithinclude the following.
1234bcd95a3SBarry Smith
1244bcd95a3SBarry Smith```
1254bcd95a3SBarry Smithtypedef struct _VecOps* VecOps;
1264bcd95a3SBarry Smithstruct _VecOps {
1274bcd95a3SBarry Smith  PetscErrorCode (*duplicate)(Vec,Vec*); /* get single vector */
1284bcd95a3SBarry Smith  PetscErrorCode (*duplicatevecs)(Vec,PetscInt,Vec**); /* get array of vectors */
1294bcd95a3SBarry Smith  PetscErrorCode (*destroyvecs)(PetscInt,Vec[]); /* free array of vectors */
1304bcd95a3SBarry Smith  PetscErrorCode (*dot)(Vec,Vec,PetscScalar*); /* z = x^H * y */
1314bcd95a3SBarry Smith  PetscErrorCode (*mdot)(Vec,PetscInt,const Vec[],PetscScalar*); /* z[j] = x dot y[j] */
1324bcd95a3SBarry Smith  PetscErrorCode (*norm)(Vec,NormType,PetscReal*); /* z = sqrt(x^H * x) */
1334bcd95a3SBarry Smith  PetscErrorCode (*tdot)(Vec,Vec,PetscScalar*); /* x'*y */
1344bcd95a3SBarry Smith  PetscErrorCode (*mtdot)(Vec,PetscInt,const Vec[],PetscScalar*);/* z[j] = x dot y[j] */
1354bcd95a3SBarry Smith  PetscErrorCode (*scale)(Vec,PetscScalar);  /* x = alpha * x   */
1364bcd95a3SBarry Smith  PetscErrorCode (*copy)(Vec,Vec); /* y = x */
1374bcd95a3SBarry Smith  PetscErrorCode (*set)(Vec,PetscScalar); /* y = alpha  */
1384bcd95a3SBarry Smith  PetscErrorCode (*swap)(Vec,Vec); /* exchange x and y */
1394bcd95a3SBarry Smith  PetscErrorCode (*axpy)(Vec,PetscScalar,Vec); /* y = y + alpha * x */
1404bcd95a3SBarry Smith  PetscErrorCode (*axpby)(Vec,PetscScalar,PetscScalar,Vec); /* y = alpha * x + beta * y*/
1414bcd95a3SBarry Smith  PetscErrorCode (*maxpy)(Vec,PetscInt,const PetscScalar*,Vec*); /* y = y + alpha[j] x[j] */
1424bcd95a3SBarry Smith  ... (AND SO ON) ...
1434bcd95a3SBarry Smith};
1444bcd95a3SBarry Smith```
1454bcd95a3SBarry Smith
1464bcd95a3SBarry Smith```
1474bcd95a3SBarry Smithstruct _p_Vec {
1484bcd95a3SBarry Smith  PetscClassId           classid;
1494bcd95a3SBarry Smith  PetscOps               *bops;
1504bcd95a3SBarry Smith  VecOps                 *ops;
1514bcd95a3SBarry Smith  MPI_Comm               comm;
1524bcd95a3SBarry Smith  PetscLogDouble         flops,time,mem;
1534bcd95a3SBarry Smith  int                    id;
1544bcd95a3SBarry Smith  int                    refct;
1554bcd95a3SBarry Smith  int                    tag;
1564bcd95a3SBarry Smith  DLList                 qlist;
1574bcd95a3SBarry Smith  OList                  olist;
1584bcd95a3SBarry Smith  char                   *type_name;
1594bcd95a3SBarry Smith  PetscObject            parent;
1604bcd95a3SBarry Smith  char                   *name;
1614bcd95a3SBarry Smith  char                   *prefix;
1624bcd95a3SBarry Smith  void                   **fortran_func_pointers;
1634bcd95a3SBarry Smith  void                   *data;     /* implementation-specific data */
1644bcd95a3SBarry Smith  PetscLayout            map;
1654bcd95a3SBarry Smith  ISLocalToGlobalMapping mapping;   /* mapping used in VecSetValuesLocal() */
1664bcd95a3SBarry Smith};
1674bcd95a3SBarry Smith```
1684bcd95a3SBarry Smith
1694bcd95a3SBarry SmithEach PETSc object begins with a `PetscClassId`, which is used for
1704bcd95a3SBarry Smitherror checking. Each different class of objects has its value for
1714bcd95a3SBarry Smith`classid`; these are used to distinguish between classes. When a new
1724bcd95a3SBarry Smithclass is created you need to call
1734bcd95a3SBarry Smith
1744bcd95a3SBarry Smith```
1754bcd95a3SBarry SmithPetscClassIdRegister(const char *classname,PetscClassId *classid);
1764bcd95a3SBarry Smith```
1774bcd95a3SBarry Smith
1784bcd95a3SBarry SmithFor example,
1794bcd95a3SBarry Smith
1804bcd95a3SBarry Smith```
1814bcd95a3SBarry SmithPetscClassIdRegister("index set",&IS_CLASSID);
1824bcd95a3SBarry Smith```
1834bcd95a3SBarry Smith
1844bcd95a3SBarry Smithyou can verify that an object is valid of a particular class with
1854bcd95a3SBarry Smith`PetscValidHeaderSpecific`, for example,
1864bcd95a3SBarry Smith
1874bcd95a3SBarry Smith```
1884bcd95a3SBarry SmithPetscValidHeaderSpecific(x,VEC_CLASSID,1);
1894bcd95a3SBarry Smith```
1904bcd95a3SBarry Smith
1914bcd95a3SBarry SmithThe third argument to this macro indicates the position in the calling
1924bcd95a3SBarry Smithsequence of the function the object was passed in. This is to generate
1934bcd95a3SBarry Smithmore complete error messages.
1944bcd95a3SBarry Smith
1954bcd95a3SBarry SmithTo check for an object of any type, use
1964bcd95a3SBarry Smith
1974bcd95a3SBarry Smith```
1984bcd95a3SBarry SmithPetscValidHeader(x,1);
1994bcd95a3SBarry Smith```
2004bcd95a3SBarry Smith
2014bcd95a3SBarry SmithThe `obj->ops` functions provide implementations of the standard methods of the object class. Each type
2024bcd95a3SBarry Smithof the class may have different function pointers in the array. Subtypes sometimes replace some of the
2034bcd95a3SBarry Smithfunction pointers of the parent, so they play the role of virtual methods in C++.
2044bcd95a3SBarry Smith
2054bcd95a3SBarry SmithPETSc code that calls these function pointers should be done via
2064bcd95a3SBarry Smith
2074bcd95a3SBarry Smith```
2084bcd95a3SBarry SmithPetscUseTypeMethod(obj,method,other arguments);
2094bcd95a3SBarry SmithPetscTryTypeMethod(obj,method,other arguments);
2104bcd95a3SBarry Smith```
2114bcd95a3SBarry Smith
2124bcd95a3SBarry SmithFor example,
2134bcd95a3SBarry Smith
2144bcd95a3SBarry Smith```
2154bcd95a3SBarry SmithPetscErrorCode XXXOp(XXX x,YYY y)
2164bcd95a3SBarry Smith{
2174bcd95a3SBarry Smith  PetscFunctionBegin;
2184bcd95a3SBarry Smith  PetscUseTypeMethod(x,op,y);
2194bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
2204bcd95a3SBarry Smith}
2214bcd95a3SBarry Smith```
2224bcd95a3SBarry Smith
2234bcd95a3SBarry SmithThe `Try` variant skips the function call if the method has not been set while the `Use` version generates an error in that case.
2244bcd95a3SBarry Smith
2254bcd95a3SBarry SmithSee also, `PetscUseMethod()`, and `PetscTryMethod()`.
2264bcd95a3SBarry Smith
2274bcd95a3SBarry Smith## Common Object Functions
2284bcd95a3SBarry Smith
2294bcd95a3SBarry SmithSeveral routines are provided for manipulating data within the header.
2304bcd95a3SBarry SmithThese include the specific functions in the PETSc common function table.
2314bcd95a3SBarry SmithThe function pointers are not called directly; rather you should call
2324bcd95a3SBarry Smith`PetscObjectFunctionName()`, where `FunctionName` is one of the
2334bcd95a3SBarry Smithfunctions listed below with the first letter of each word capitalized.
2344bcd95a3SBarry Smith
2357f296bb3SBarry Smith`PetscObjectGetComm()` calls the `getcomm(PetscObject,MPI_Comm*)` function point which obtains the MPI communicator
2364bcd95a3SBarry Smithassociated with this object.
2374bcd95a3SBarry Smith
2387f296bb3SBarry Smith`PetscObjectView()` calls the `view(PetscObject,PetscViewer)` function point which allows you to store or visualize the
2397f296bb3SBarry Smithdata inside an object. If the `PetscViewer` is `NULL`, then it should cause the
2407f296bb3SBarry Smithobject to print information on the object to `stdout`.
2414bcd95a3SBarry Smith
2427f296bb3SBarry Smith`PetscObjectDestroy()` calls the  `destroy(PetscObject)` function pointer which causes the reference count of the object to be
2434bcd95a3SBarry Smithdecreased by one or the object to be destroyed and all memory used by
2444bcd95a3SBarry Smiththe object to be freed when the reference count drops to zero. If the
2457f296bb3SBarry Smithobject has any other objects composed with it, the `PetscObjectDestroy()` function is called on them.
2464bcd95a3SBarry Smith
2477f296bb3SBarry Smith`PetscObjectCompose()` calls the `compose(PetscObject,const char *name,PetscObject)` function pointer  which associates the
2484bcd95a3SBarry Smithsecond object with the first object and increases the reference count of
2494bcd95a3SBarry Smiththe second object. If an object with the same name was previously
2504bcd95a3SBarry Smithcomposed, that object is dereferenced and replaced with the new object.
2517f296bb3SBarry SmithIf the second object is `NULL` and an object with the same name has
2527f296bb3SBarry Smithalready been composed, that object is dereferenced (the `PetscObjectDestroy()`
2534bcd95a3SBarry Smithfunction is called on it, and that object is removed from the first
2544bcd95a3SBarry Smithobject). This is a way to remove, by name, an object that was previously
2554bcd95a3SBarry Smithcomposed.
2564bcd95a3SBarry Smith
2577f296bb3SBarry Smith`PetscObjectQuery()` calls the `query(PetscObject,const char *name,PetscObject*)` function pointer which retrieves an object
2584bcd95a3SBarry Smiththat was previously composed with the first object via
2597f296bb3SBarry Smith`PetscObjectCompose()`. It retrieves a `NULL` if no object with that
2604bcd95a3SBarry Smithname was previously composed.
2614bcd95a3SBarry Smith
2627f296bb3SBarry Smith`PetscObjectComposeFunction()` calls the `composefunction(PetscObject,const char *name,void *func)` function pointer which associates
2634bcd95a3SBarry Smitha function pointer with an object. If the object already had a composed
2644bcd95a3SBarry Smithfunction with the same name, the old one is replaced. If `func` is
2654bcd95a3SBarry Smith`NULL`, the existing function is removed from the object. The string
2664bcd95a3SBarry Smith`name` is the character string name of the function.
2674bcd95a3SBarry Smith
2684bcd95a3SBarry SmithFor example, `fname` may be `PCCreate_LU`.
2694bcd95a3SBarry Smith
2707f296bb3SBarry Smith`PetscObjectQueryFunction()` calls the `queryfunction(PetscObject,const char *name,void **func)` function pointer which retrieves a
2714bcd95a3SBarry Smithfunction pointer that was associated with the object via
2724bcd95a3SBarry Smith`PetscObjectComposeFunction()`. If dynamic libraries are used, the
2734bcd95a3SBarry Smithfunction is loaded into memory at this time (if it has not been
2747f296bb3SBarry Smithpreviously loaded), not when the `PetscObjectComposeFunction()` routine was
2754bcd95a3SBarry Smithcalled.
2764bcd95a3SBarry Smith
2774bcd95a3SBarry SmithSince the object composition allows one to compose PETSc objects
2784bcd95a3SBarry Smithwith PETSc objects, PETSc provides the
2794bcd95a3SBarry Smithconvenience object `PetscContainer`, created with the routine
2804bcd95a3SBarry Smith`PetscContainerCreate(MPI_Comm,PetscContainer*)`, to allow wrapping any
2814bcd95a3SBarry Smithkind of data into a PETSc object that can then be composed with a PETSc
2827f296bb3SBarry Smithobject. One can also use `PetscObjectContainerCompose()` and `PetscObjectContainerQuery()` to compose
2834bcd95a3SBarry Smitharbitrary pointers with a PETSc object.
2844bcd95a3SBarry Smith
2854bcd95a3SBarry Smith## Object Function Implementation
2864bcd95a3SBarry Smith
2874bcd95a3SBarry SmithThis section discusses how PETSc implements the `compose()`,
2884bcd95a3SBarry Smith`query()`, `composefunction()`, and `queryfunction()` functions
2894bcd95a3SBarry Smithfor its object implementations. Other PETSc-compatible class
2904bcd95a3SBarry Smithimplementations are free to manage these functions in any manner; but
2914bcd95a3SBarry Smithunless there is a specific reason, they should use the PETSc defaults so
2924bcd95a3SBarry Smiththat the library writer does not have to “reinvent the wheel.”
2934bcd95a3SBarry Smith
2944bcd95a3SBarry Smith### Compose and Query Objects
2954bcd95a3SBarry Smith
2964bcd95a3SBarry SmithIn
2974bcd95a3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/sys/objects/olist.c.html">src/sys/objects/olist.c</a>
2984bcd95a3SBarry SmithPETSc defines a C `struct`
2994bcd95a3SBarry Smith
3004bcd95a3SBarry Smith```
3014bcd95a3SBarry Smithtypedef struct _PetscObjectList* PetscObjectList;
3024bcd95a3SBarry Smithstruct _PetscObjectList {
3034bcd95a3SBarry Smith    char             name[128];
3044bcd95a3SBarry Smith    PetscObject      obj;
3054bcd95a3SBarry Smith    PetscObjectList  next;
3064bcd95a3SBarry Smith};
3074bcd95a3SBarry Smith```
3084bcd95a3SBarry Smith
3094bcd95a3SBarry Smithfrom which linked lists of composed objects may be constructed. The
3104bcd95a3SBarry Smithroutines to manipulate these elementary objects are
3114bcd95a3SBarry Smith
3124bcd95a3SBarry Smith```
3134bcd95a3SBarry Smithint PetscObjectListAdd(PetscObjectList *fl,const char *name,PetscObject obj);
3144bcd95a3SBarry Smithint PetscObjectListDestroy(PetscObjectList *fl);
3154bcd95a3SBarry Smithint PetscObjectListFind(PetscObjectList fl,const char *name,PetscObject *obj)
3164bcd95a3SBarry Smithint PetscObjectListDuplicate(PetscObjectList fl,PetscObjectList *nl);
3174bcd95a3SBarry Smith```
3184bcd95a3SBarry Smith
3194bcd95a3SBarry SmithThe function `PetscObjectListAdd()` will create the initial
3204bcd95a3SBarry SmithPetscObjectList if the argument `fl` points to a NULL.
3214bcd95a3SBarry Smith
3224bcd95a3SBarry SmithThe PETSc object `compose()` and `query()` functions are as follows
3234bcd95a3SBarry Smith(defined in
3244bcd95a3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/sys/objects/inherit.c.html">src/sys/objects/inherit.c</a>
3254bcd95a3SBarry Smith
3264bcd95a3SBarry Smith```
3274bcd95a3SBarry SmithPetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char *name,PetscObject ptr)
3284bcd95a3SBarry Smith{
3294bcd95a3SBarry Smith  PetscFunctionBegin;
3304bcd95a3SBarry Smith  PetscCall(PetscObjectListAdd(&obj->olist,name,ptr));
3314bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
3324bcd95a3SBarry Smith}
3334bcd95a3SBarry Smith
3344bcd95a3SBarry SmithPetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char *name,PetscObject *ptr)
3354bcd95a3SBarry Smith{
3364bcd95a3SBarry Smith  PetscFunctionBegin;
3374bcd95a3SBarry Smith  PetscCall(PetscObjectListFind(obj->olist,name,ptr));
3384bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
3394bcd95a3SBarry Smith}
3404bcd95a3SBarry Smith```
3414bcd95a3SBarry Smith
3424bcd95a3SBarry Smith### Compose and Query Functions
3434bcd95a3SBarry Smith
3444bcd95a3SBarry SmithPETSc allows you to compose functions by specifying a name and function
3454bcd95a3SBarry Smithpointer. In
3464bcd95a3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/sys/dll/reg.c.html">src/sys/dll/reg.c</a>
3474bcd95a3SBarry SmithPETSc defines the following linked list structure.
3484bcd95a3SBarry Smith
3494bcd95a3SBarry Smith```
3504bcd95a3SBarry Smithstruct _n_PetscFunctionList {
3514bcd95a3SBarry Smith  void              (*routine)(void);    /* the routine */
3524bcd95a3SBarry Smith  char              *name;               /* string to identify routine */
3534bcd95a3SBarry Smith  PetscFunctionList next;                /* next pointer */
3544bcd95a3SBarry Smith  PetscFunctionList next_list;           /* used to maintain list of all lists for freeing */
3554bcd95a3SBarry Smith};
3564bcd95a3SBarry Smith```
3574bcd95a3SBarry Smith
3584bcd95a3SBarry SmithEach PETSc object contains a `PetscFunctionList` object. The
3594bcd95a3SBarry Smith`composefunction()` and `queryfunction()` are given by the
3604bcd95a3SBarry Smithfollowing.
3614bcd95a3SBarry Smith
3624bcd95a3SBarry Smith```
363*57d50842SBarry SmithPetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj, const char *name, PetscErrorCodeFn *ptr)
3644bcd95a3SBarry Smith{
3654bcd95a3SBarry Smith  PetscFunctionBegin;
3664bcd95a3SBarry Smith  PetscCall(PetscFunctionListAdd(&obj->qlist,name,fname,ptr));
3674bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
3684bcd95a3SBarry Smith}
3694bcd95a3SBarry Smith
370*57d50842SBarry SmithPetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj, const char *name, PetscErrorCodeFn **ptr)
3714bcd95a3SBarry Smith{
3724bcd95a3SBarry Smith  PetscFunctionBegin;
3734bcd95a3SBarry Smith  PetscCall(PetscFunctionListFind(obj->qlist,name,ptr));
3744bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
3754bcd95a3SBarry Smith}
3764bcd95a3SBarry Smith```
3774bcd95a3SBarry Smith
3784bcd95a3SBarry SmithIn addition to using the `PetscFunctionList` mechanism to compose
3794bcd95a3SBarry Smithfunctions into PETSc objects, it is also used to allow registration of
3804bcd95a3SBarry Smithnew class implementations; for example, new preconditioners.
3814bcd95a3SBarry Smith
3824bcd95a3SBarry SmithPETSc code that calls composed functions should be done via
3834bcd95a3SBarry Smith
3844bcd95a3SBarry Smith```
3854bcd95a3SBarry SmithPetscUseMethod(obj,"method",(Argument types),(argument variables));
3864bcd95a3SBarry SmithPetscTryMethod(obj,"method",(Argument types),(argument variables));
3874bcd95a3SBarry Smith```
3884bcd95a3SBarry Smith
3894bcd95a3SBarry SmithFor example,
3904bcd95a3SBarry Smith
3914bcd95a3SBarry Smith```
3924bcd95a3SBarry SmithPetscErrorCode  KSPGMRESSetRestart(KSP ksp, PetscInt restart)
3934bcd95a3SBarry Smith{
3944bcd95a3SBarry Smith  PetscFunctionBegin;
3954bcd95a3SBarry Smith  PetscValidLogicalCollectiveInt(ksp,restart,2);
3964bcd95a3SBarry Smith
3974bcd95a3SBarry Smith  PetscTryMethod(ksp,"KSPGMRESSetRestart_C",(KSP,PetscInt),(ksp,restart));
3984bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
3994bcd95a3SBarry Smith}
4004bcd95a3SBarry Smith```
4014bcd95a3SBarry Smith
4024bcd95a3SBarry SmithThe `Try` variant skips the function call if the method has not been composed with
4034bcd95a3SBarry Smiththe object while the `Use` version generates an error in that case.
4044bcd95a3SBarry SmithSee also, `PetscUseTypeMethod()`, and `PetscTryTypeMethod()`.
4054bcd95a3SBarry Smith
4064bcd95a3SBarry Smith### Simple PETSc Objects
4074bcd95a3SBarry Smith
4084bcd95a3SBarry SmithSome simple PETSc objects do not need `PETSCHEADER` and the associated
4094bcd95a3SBarry Smithfunctionality. These objects are internally named as `_n_<class>` as
4104bcd95a3SBarry Smithopposed to `_p_<class>`, for example, `_n_PetscFunctionList` vs `_p_Vec`.
4114bcd95a3SBarry Smith
4124bcd95a3SBarry Smith## PETSc Packages
4134bcd95a3SBarry Smith
4144bcd95a3SBarry SmithThe PETSc source code is divided into the following library-level
4154bcd95a3SBarry Smithpackages: `Sys`, `Vec`, `Mat`, `DM`, `KSP`, `SNES`, `TS`,
4164bcd95a3SBarry Smith`Tao`. Each of these has a directory under the `src` directory in
4174bcd95a3SBarry Smiththe PETSc tree and, optionally, can be compiled into separate libraries.
4184bcd95a3SBarry SmithEach package defines one or more classes; for example, the `KSP`
4194bcd95a3SBarry Smithpackage defines the `KSP` and `PC` classes, as well as several
4204bcd95a3SBarry Smithutility classes. In addition, each library-level package may contain
4214bcd95a3SBarry Smithseveral class-level packages associated with individual classes in the
4224bcd95a3SBarry Smithlibrary-level package. In general, most “important” classes in PETSc
4234bcd95a3SBarry Smithhave their own class level package. Each package provides a registration
4244bcd95a3SBarry Smithfunction `XXXInitializePackage()`, for example
4254bcd95a3SBarry Smith`KSPInitializePackage()`, which registers all the classes and events
4264bcd95a3SBarry Smithfor that package. Each package also registers a finalization routine,
4274bcd95a3SBarry Smith`XXXFinalizePackage()`, that releases all the resources used in
4284bcd95a3SBarry Smithregistering the package, using `PetscRegisterFinalize()`. The
4294bcd95a3SBarry Smithregistration for each package is performed “on demand” the first time a
4304bcd95a3SBarry Smithclass in the package is utilized. This is handled, for example, with
4314bcd95a3SBarry Smithcode such as
4324bcd95a3SBarry Smith
4334bcd95a3SBarry Smith```
4344bcd95a3SBarry SmithPetscErrorCode  VecCreate(MPI_Comm comm, Vec *vec)
4354bcd95a3SBarry Smith{
4364bcd95a3SBarry Smith  Vec            v;
4374bcd95a3SBarry Smith
4384bcd95a3SBarry Smith  PetscFunctionBegin;
4394bcd95a3SBarry Smith  PetscAssertPointer(vec,2);
4404bcd95a3SBarry Smith  *vec = NULL;
4414bcd95a3SBarry Smith  VecInitializePackage();
4424bcd95a3SBarry Smith  ...
4434bcd95a3SBarry Smith```
444