xref: /petsc/doc/developers/objects.md (revision 4bcd95a3096906c174cd1a87ff30988eadf5695d)
1*4bcd95a3SBarry Smith# Basic Object Design and Implementation
2*4bcd95a3SBarry Smith
3*4bcd95a3SBarry SmithPETSc is designed by using strong data encapsulation. Hence, any
4*4bcd95a3SBarry Smithcollection of data (for instance, a sparse matrix) is stored in a way
5*4bcd95a3SBarry Smiththat is completely private from the application code. The application
6*4bcd95a3SBarry Smithcode can manipulate the data only through a well-defined interface,
7*4bcd95a3SBarry Smithsince it does *not* "know" how the data is stored internally.
8*4bcd95a3SBarry Smith
9*4bcd95a3SBarry Smith## Introduction
10*4bcd95a3SBarry Smith
11*4bcd95a3SBarry SmithPETSc is designed around several classes including `Vec` (vectors) and
12*4bcd95a3SBarry Smith`Mat` (matrices, both dense and sparse). Each class is implemented by
13*4bcd95a3SBarry Smithusing a C `struct` that contains the data and function pointers for
14*4bcd95a3SBarry Smithoperations on the data (much like virtual functions in C++ classes).
15*4bcd95a3SBarry SmithEach class consists of three parts:
16*4bcd95a3SBarry Smith
17*4bcd95a3SBarry SmithA (small) common part shared by all PETSc classes (for example, both
18*4bcd95a3SBarry Smith`KSP` and `PC` have this same header).
19*4bcd95a3SBarry Smith
20*4bcd95a3SBarry SmithAnother common part shared by all PETSc implementations of the class
21*4bcd95a3SBarry Smith(for example, both `KSPGMRES` and `KSPCG` have this common
22*4bcd95a3SBarry Smithsubheader).
23*4bcd95a3SBarry Smith
24*4bcd95a3SBarry SmithA private part used by only one particular implementation written in
25*4bcd95a3SBarry SmithPETSc.
26*4bcd95a3SBarry Smith
27*4bcd95a3SBarry SmithFor example, all matrix (`Mat`) classes share a function table of
28*4bcd95a3SBarry Smithoperations that may be performed on the matrix; all PETSc matrix
29*4bcd95a3SBarry Smithimplementations share some additional data fields, including matrix
30*4bcd95a3SBarry Smithparallel layout, while a particular matrix implementation in PETSc (say
31*4bcd95a3SBarry Smithcompressed sparse row) has its own data fields for storing the actual
32*4bcd95a3SBarry Smithmatrix values and sparsity pattern. This will be explained in more
33*4bcd95a3SBarry Smithdetail in the following sections. New class implementations *must* use
34*4bcd95a3SBarry Smiththe PETSc common part.
35*4bcd95a3SBarry Smith
36*4bcd95a3SBarry SmithWe will use `<class>_<implementation>` to denote the actual source code
37*4bcd95a3SBarry Smithand data structures used for a particular implementation of an object
38*4bcd95a3SBarry Smiththat has the `<class>` interface.
39*4bcd95a3SBarry Smith
40*4bcd95a3SBarry Smith## Organization of the Source Code
41*4bcd95a3SBarry Smith
42*4bcd95a3SBarry SmithEach class has the following organization.
43*4bcd95a3SBarry Smith
44*4bcd95a3SBarry SmithIts own, application-public, include file `include/petsc<class>.h`.
45*4bcd95a3SBarry Smith
46*4bcd95a3SBarry SmithIts own directory, `src/<class>` or `src/<package>/<class>`.
47*4bcd95a3SBarry Smith
48*4bcd95a3SBarry SmithA data structure defined in the file
49*4bcd95a3SBarry Smith`include/petsc/private/<class>impl.h`. This data structure is shared
50*4bcd95a3SBarry Smithby all the different PETSc implementations of the class. For example,
51*4bcd95a3SBarry Smithfor matrices it is shared by dense, sparse, parallel, and sequential
52*4bcd95a3SBarry Smithformats.
53*4bcd95a3SBarry Smith
54*4bcd95a3SBarry SmithAn abstract interface that defines the application-callable functions
55*4bcd95a3SBarry Smithfor the class. These are defined in the directory
56*4bcd95a3SBarry Smith`src/<class>/interface`. This is how polymorphism is supported with
57*4bcd95a3SBarry Smithcode that implements the abstract interface to the operations on the
58*4bcd95a3SBarry Smithobject. Essentially, these routines do some error checking of arguments
59*4bcd95a3SBarry Smithand logging of profiling information and then call the function
60*4bcd95a3SBarry Smithappropriate for the particular implementation of the object. The name of
61*4bcd95a3SBarry Smiththe abstract function is `<class>Operation`, for instance,
62*4bcd95a3SBarry Smith`MatMult()` or `PCCreate(`), while the name of a particular
63*4bcd95a3SBarry Smithimplementation is `<class>Operation_<implementation>`, for instance,
64*4bcd95a3SBarry Smith`MatMult_SeqAIJ()` or `PCCreate_ILU()`. These naming conventions are
65*4bcd95a3SBarry Smithused to simplify code maintenance (also see Section [sec:stylenames]).
66*4bcd95a3SBarry Smith
67*4bcd95a3SBarry SmithOne or more actual implementations of the class (for example, sparse
68*4bcd95a3SBarry Smithuniprocessor and parallel matrices implemented with the AIJ storage
69*4bcd95a3SBarry Smithformat). These are each in a subdirectory of `src/<class>/impls`.
70*4bcd95a3SBarry SmithExcept in rare circumstances, data structures defined here should not be
71*4bcd95a3SBarry Smithreferenced from outside this directory.
72*4bcd95a3SBarry Smith
73*4bcd95a3SBarry SmithEach type of object (for instance, a vector) is defined in its own
74*4bcd95a3SBarry Smithpublic include file, by `typedef _p_<class>* <class>`; (for example,
75*4bcd95a3SBarry Smith`typedef _p_Vec* Vec;`). This organization allows the compiler to
76*4bcd95a3SBarry Smithperform type checking on all subroutine calls while at the same time
77*4bcd95a3SBarry Smithcompletely removing the details of the implementation of `_p_<class>`
78*4bcd95a3SBarry Smithfrom the application code. This capability is extremely important
79*4bcd95a3SBarry Smithbecause it allows the library internals to be changed without altering
80*4bcd95a3SBarry Smithor recompiling the application code.
81*4bcd95a3SBarry Smith
82*4bcd95a3SBarry Smith## Common Object Header
83*4bcd95a3SBarry Smith
84*4bcd95a3SBarry SmithAll PETSc objects (derived from the base class ``PetscObject``) have the following common header structures
85*4bcd95a3SBarry Smithdefined in
86*4bcd95a3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/include/petsc/private/petscimpl.h.html">include/petsc/private/petscimpl.h</a>
87*4bcd95a3SBarry Smith
88*4bcd95a3SBarry Smith```
89*4bcd95a3SBarry Smithtypedef struct {
90*4bcd95a3SBarry Smith  PetscErrorCode (*getcomm)(PetscObject,MPI_Comm*);
91*4bcd95a3SBarry Smith  PetscErrorCode (*view)(PetscObject,Viewer);
92*4bcd95a3SBarry Smith  PetscErrorCode (*destroy)(PetscObject);
93*4bcd95a3SBarry Smith  PetscErrorCode (*query)(PetscObject,const char*,PetscObject*);
94*4bcd95a3SBarry Smith  PetscErrorCode (*compose)(PetscObject,const char*,PetscObject);
95*4bcd95a3SBarry Smith  PetscErrorCode (*composefunction)(PetscObject,const char*,void(*)(void));
96*4bcd95a3SBarry Smith  PetscErrorCode (*queryfunction)(PetscObject,const char*,void (**)(void));
97*4bcd95a3SBarry Smith} PetscOps;
98*4bcd95a3SBarry Smith```
99*4bcd95a3SBarry Smith
100*4bcd95a3SBarry Smith```
101*4bcd95a3SBarry Smithstruct _p_<class> {
102*4bcd95a3SBarry Smith  PetscClassId     classid;
103*4bcd95a3SBarry Smith  PetscOps         *bops;
104*4bcd95a3SBarry Smith  <class>Ops       *ops;
105*4bcd95a3SBarry Smith  MPI_Comm         comm;
106*4bcd95a3SBarry Smith  PetscLogDouble   flops,time,mem;
107*4bcd95a3SBarry Smith  int              id;
108*4bcd95a3SBarry Smith  int              refct;
109*4bcd95a3SBarry Smith  int              tag;
110*4bcd95a3SBarry Smith  DLList           qlist;
111*4bcd95a3SBarry Smith  OList            olist;
112*4bcd95a3SBarry Smith  char             *type_name;
113*4bcd95a3SBarry Smith  PetscObject      parent;
114*4bcd95a3SBarry Smith  char             *name;
115*4bcd95a3SBarry Smith  char             *prefix;
116*4bcd95a3SBarry Smith  void             *cpp;
117*4bcd95a3SBarry Smith  void             **fortran_func_pointers;
118*4bcd95a3SBarry Smith  ..........
119*4bcd95a3SBarry Smith  CLASS-SPECIFIC DATASTRUCTURES
120*4bcd95a3SBarry Smith};
121*4bcd95a3SBarry Smith```
122*4bcd95a3SBarry Smith
123*4bcd95a3SBarry SmithHere `<class>ops` is a function table (like the `PetscOps` above)
124*4bcd95a3SBarry Smiththat contains the function pointers for the operations specific to that
125*4bcd95a3SBarry Smithclass. For example, the PETSc vector class object operations in
126*4bcd95a3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/include/petsc/private/vecimpl.h.html">include/petsc/private/vecimpl.h</a>
127*4bcd95a3SBarry Smithinclude the following.
128*4bcd95a3SBarry Smith
129*4bcd95a3SBarry Smith```
130*4bcd95a3SBarry Smithtypedef struct _VecOps* VecOps;
131*4bcd95a3SBarry Smithstruct _VecOps {
132*4bcd95a3SBarry Smith  PetscErrorCode (*duplicate)(Vec,Vec*); /* get single vector */
133*4bcd95a3SBarry Smith  PetscErrorCode (*duplicatevecs)(Vec,PetscInt,Vec**); /* get array of vectors */
134*4bcd95a3SBarry Smith  PetscErrorCode (*destroyvecs)(PetscInt,Vec[]); /* free array of vectors */
135*4bcd95a3SBarry Smith  PetscErrorCode (*dot)(Vec,Vec,PetscScalar*); /* z = x^H * y */
136*4bcd95a3SBarry Smith  PetscErrorCode (*mdot)(Vec,PetscInt,const Vec[],PetscScalar*); /* z[j] = x dot y[j] */
137*4bcd95a3SBarry Smith  PetscErrorCode (*norm)(Vec,NormType,PetscReal*); /* z = sqrt(x^H * x) */
138*4bcd95a3SBarry Smith  PetscErrorCode (*tdot)(Vec,Vec,PetscScalar*); /* x'*y */
139*4bcd95a3SBarry Smith  PetscErrorCode (*mtdot)(Vec,PetscInt,const Vec[],PetscScalar*);/* z[j] = x dot y[j] */
140*4bcd95a3SBarry Smith  PetscErrorCode (*scale)(Vec,PetscScalar);  /* x = alpha * x   */
141*4bcd95a3SBarry Smith  PetscErrorCode (*copy)(Vec,Vec); /* y = x */
142*4bcd95a3SBarry Smith  PetscErrorCode (*set)(Vec,PetscScalar); /* y = alpha  */
143*4bcd95a3SBarry Smith  PetscErrorCode (*swap)(Vec,Vec); /* exchange x and y */
144*4bcd95a3SBarry Smith  PetscErrorCode (*axpy)(Vec,PetscScalar,Vec); /* y = y + alpha * x */
145*4bcd95a3SBarry Smith  PetscErrorCode (*axpby)(Vec,PetscScalar,PetscScalar,Vec); /* y = alpha * x + beta * y*/
146*4bcd95a3SBarry Smith  PetscErrorCode (*maxpy)(Vec,PetscInt,const PetscScalar*,Vec*); /* y = y + alpha[j] x[j] */
147*4bcd95a3SBarry Smith  ... (AND SO ON) ...
148*4bcd95a3SBarry Smith};
149*4bcd95a3SBarry Smith```
150*4bcd95a3SBarry Smith
151*4bcd95a3SBarry Smith```
152*4bcd95a3SBarry Smithstruct _p_Vec {
153*4bcd95a3SBarry Smith  PetscClassId           classid;
154*4bcd95a3SBarry Smith  PetscOps               *bops;
155*4bcd95a3SBarry Smith  VecOps                 *ops;
156*4bcd95a3SBarry Smith  MPI_Comm               comm;
157*4bcd95a3SBarry Smith  PetscLogDouble         flops,time,mem;
158*4bcd95a3SBarry Smith  int                    id;
159*4bcd95a3SBarry Smith  int                    refct;
160*4bcd95a3SBarry Smith  int                    tag;
161*4bcd95a3SBarry Smith  DLList                 qlist;
162*4bcd95a3SBarry Smith  OList                  olist;
163*4bcd95a3SBarry Smith  char                   *type_name;
164*4bcd95a3SBarry Smith  PetscObject            parent;
165*4bcd95a3SBarry Smith  char                   *name;
166*4bcd95a3SBarry Smith  char                   *prefix;
167*4bcd95a3SBarry Smith  void                   **fortran_func_pointers;
168*4bcd95a3SBarry Smith  void                   *data;     /* implementation-specific data */
169*4bcd95a3SBarry Smith  PetscLayout            map;
170*4bcd95a3SBarry Smith  ISLocalToGlobalMapping mapping;   /* mapping used in VecSetValuesLocal() */
171*4bcd95a3SBarry Smith};
172*4bcd95a3SBarry Smith```
173*4bcd95a3SBarry Smith
174*4bcd95a3SBarry SmithEach PETSc object begins with a `PetscClassId`, which is used for
175*4bcd95a3SBarry Smitherror checking. Each different class of objects has its value for
176*4bcd95a3SBarry Smith`classid`; these are used to distinguish between classes. When a new
177*4bcd95a3SBarry Smithclass is created you need to call
178*4bcd95a3SBarry Smith
179*4bcd95a3SBarry Smith```
180*4bcd95a3SBarry SmithPetscClassIdRegister(const char *classname,PetscClassId *classid);
181*4bcd95a3SBarry Smith```
182*4bcd95a3SBarry Smith
183*4bcd95a3SBarry SmithFor example,
184*4bcd95a3SBarry Smith
185*4bcd95a3SBarry Smith```
186*4bcd95a3SBarry SmithPetscClassIdRegister("index set",&IS_CLASSID);
187*4bcd95a3SBarry Smith```
188*4bcd95a3SBarry Smith
189*4bcd95a3SBarry Smithyou can verify that an object is valid of a particular class with
190*4bcd95a3SBarry Smith`PetscValidHeaderSpecific`, for example,
191*4bcd95a3SBarry Smith
192*4bcd95a3SBarry Smith```
193*4bcd95a3SBarry SmithPetscValidHeaderSpecific(x,VEC_CLASSID,1);
194*4bcd95a3SBarry Smith```
195*4bcd95a3SBarry Smith
196*4bcd95a3SBarry SmithThe third argument to this macro indicates the position in the calling
197*4bcd95a3SBarry Smithsequence of the function the object was passed in. This is to generate
198*4bcd95a3SBarry Smithmore complete error messages.
199*4bcd95a3SBarry Smith
200*4bcd95a3SBarry SmithTo check for an object of any type, use
201*4bcd95a3SBarry Smith
202*4bcd95a3SBarry Smith```
203*4bcd95a3SBarry SmithPetscValidHeader(x,1);
204*4bcd95a3SBarry Smith```
205*4bcd95a3SBarry Smith
206*4bcd95a3SBarry SmithThe `obj->ops` functions provide implementations of the standard methods of the object class. Each type
207*4bcd95a3SBarry Smithof the class may have different function pointers in the array. Subtypes sometimes replace some of the
208*4bcd95a3SBarry Smithfunction pointers of the parent, so they play the role of virtual methods in C++.
209*4bcd95a3SBarry Smith
210*4bcd95a3SBarry SmithPETSc code that calls these function pointers should be done via
211*4bcd95a3SBarry Smith
212*4bcd95a3SBarry Smith```
213*4bcd95a3SBarry SmithPetscUseTypeMethod(obj,method,other arguments);
214*4bcd95a3SBarry SmithPetscTryTypeMethod(obj,method,other arguments);
215*4bcd95a3SBarry Smith```
216*4bcd95a3SBarry Smith
217*4bcd95a3SBarry SmithFor example,
218*4bcd95a3SBarry Smith
219*4bcd95a3SBarry Smith```
220*4bcd95a3SBarry SmithPetscErrorCode XXXOp(XXX x,YYY y)
221*4bcd95a3SBarry Smith{
222*4bcd95a3SBarry Smith  PetscFunctionBegin;
223*4bcd95a3SBarry Smith  PetscUseTypeMethod(x,op,y);
224*4bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
225*4bcd95a3SBarry Smith}
226*4bcd95a3SBarry Smith```
227*4bcd95a3SBarry Smith
228*4bcd95a3SBarry SmithThe `Try` variant skips the function call if the method has not been set while the `Use` version generates an error in that case.
229*4bcd95a3SBarry Smith
230*4bcd95a3SBarry SmithSee also, `PetscUseMethod()`, and `PetscTryMethod()`.
231*4bcd95a3SBarry Smith
232*4bcd95a3SBarry Smith## Common Object Functions
233*4bcd95a3SBarry Smith
234*4bcd95a3SBarry SmithSeveral routines are provided for manipulating data within the header.
235*4bcd95a3SBarry SmithThese include the specific functions in the PETSc common function table.
236*4bcd95a3SBarry SmithThe function pointers are not called directly; rather you should call
237*4bcd95a3SBarry Smith`PetscObjectFunctionName()`, where `FunctionName` is one of the
238*4bcd95a3SBarry Smithfunctions listed below with the first letter of each word capitalized.
239*4bcd95a3SBarry Smith
240*4bcd95a3SBarry Smith``PetscObjectGetComm()`` calls the ``getcomm(PetscObject,MPI_Comm*)`` function point which obtains the MPI communicator
241*4bcd95a3SBarry Smithassociated with this object.
242*4bcd95a3SBarry Smith
243*4bcd95a3SBarry Smith``PetscObjectView()`` calls the ``view(PetscObject,PetscViewer)`` function point which allows you to store or visualize the
244*4bcd95a3SBarry Smithdata inside an object. If the ``PetscViewer`` is ``NULL``, then it should cause the
245*4bcd95a3SBarry Smithobject to print information on the object to ``stdout``.
246*4bcd95a3SBarry Smith
247*4bcd95a3SBarry Smith``PetscObjectDestroy()`` calls the  ``destroy(PetscObject)`` function pointer which causes the reference count of the object to be
248*4bcd95a3SBarry Smithdecreased by one or the object to be destroyed and all memory used by
249*4bcd95a3SBarry Smiththe object to be freed when the reference count drops to zero. If the
250*4bcd95a3SBarry Smithobject has any other objects composed with it, the ``PetscObjectDestroy()`` function is called on them.
251*4bcd95a3SBarry Smith
252*4bcd95a3SBarry Smith``PetscObjectCompose()`` calls the ``compose(PetscObject,const char *name,PetscObject)`` function pointer  which associates the
253*4bcd95a3SBarry Smithsecond object with the first object and increases the reference count of
254*4bcd95a3SBarry Smiththe second object. If an object with the same name was previously
255*4bcd95a3SBarry Smithcomposed, that object is dereferenced and replaced with the new object.
256*4bcd95a3SBarry SmithIf the second object is ``NULL`` and an object with the same name has
257*4bcd95a3SBarry Smithalready been composed, that object is dereferenced (the ``PetscObjectDestroy()``
258*4bcd95a3SBarry Smithfunction is called on it, and that object is removed from the first
259*4bcd95a3SBarry Smithobject). This is a way to remove, by name, an object that was previously
260*4bcd95a3SBarry Smithcomposed.
261*4bcd95a3SBarry Smith
262*4bcd95a3SBarry Smith``PetscObjectQuery()`` calls the ``query(PetscObject,const char *name,PetscObject*)`` function pointer which retrieves an object
263*4bcd95a3SBarry Smiththat was previously composed with the first object via
264*4bcd95a3SBarry Smith``PetscObjectCompose()``. It retrieves a ``NULL`` if no object with that
265*4bcd95a3SBarry Smithname was previously composed.
266*4bcd95a3SBarry Smith
267*4bcd95a3SBarry Smith``PetscObjectComposeFunction()`` calls the ``composefunction(PetscObject,const char *name,void *func)`` function pointer which associates
268*4bcd95a3SBarry Smitha function pointer with an object. If the object already had a composed
269*4bcd95a3SBarry Smithfunction with the same name, the old one is replaced. If `func` is
270*4bcd95a3SBarry Smith`NULL`, the existing function is removed from the object. The string
271*4bcd95a3SBarry Smith`name` is the character string name of the function.
272*4bcd95a3SBarry Smith
273*4bcd95a3SBarry SmithFor example, `fname` may be `PCCreate_LU`.
274*4bcd95a3SBarry Smith
275*4bcd95a3SBarry Smith``PetscObjectQueryFunction()`` calls the ```queryfunction(PetscObject,const char *name,void **func)`` function pointer which retrieves a
276*4bcd95a3SBarry Smithfunction pointer that was associated with the object via
277*4bcd95a3SBarry Smith`PetscObjectComposeFunction()`. If dynamic libraries are used, the
278*4bcd95a3SBarry Smithfunction is loaded into memory at this time (if it has not been
279*4bcd95a3SBarry Smithpreviously loaded), not when the ``PetscObjectComposeFunction()`` routine was
280*4bcd95a3SBarry Smithcalled.
281*4bcd95a3SBarry Smith
282*4bcd95a3SBarry SmithSince the object composition allows one to compose PETSc objects
283*4bcd95a3SBarry Smithwith PETSc objects, PETSc provides the
284*4bcd95a3SBarry Smithconvenience object `PetscContainer`, created with the routine
285*4bcd95a3SBarry Smith`PetscContainerCreate(MPI_Comm,PetscContainer*)`, to allow wrapping any
286*4bcd95a3SBarry Smithkind of data into a PETSc object that can then be composed with a PETSc
287*4bcd95a3SBarry Smithobject. One can also use ``PetscObjectContainerCompose()`` and ``PetscObjectContainerQuery()`` to compose
288*4bcd95a3SBarry Smitharbitrary pointers with a PETSc object.
289*4bcd95a3SBarry Smith
290*4bcd95a3SBarry Smith## Object Function Implementation
291*4bcd95a3SBarry Smith
292*4bcd95a3SBarry SmithThis section discusses how PETSc implements the `compose()`,
293*4bcd95a3SBarry Smith`query()`, `composefunction()`, and `queryfunction()` functions
294*4bcd95a3SBarry Smithfor its object implementations. Other PETSc-compatible class
295*4bcd95a3SBarry Smithimplementations are free to manage these functions in any manner; but
296*4bcd95a3SBarry Smithunless there is a specific reason, they should use the PETSc defaults so
297*4bcd95a3SBarry Smiththat the library writer does not have to “reinvent the wheel.”
298*4bcd95a3SBarry Smith
299*4bcd95a3SBarry Smith### Compose and Query Objects
300*4bcd95a3SBarry Smith
301*4bcd95a3SBarry SmithIn
302*4bcd95a3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/sys/objects/olist.c.html">src/sys/objects/olist.c</a>
303*4bcd95a3SBarry SmithPETSc defines a C `struct`
304*4bcd95a3SBarry Smith
305*4bcd95a3SBarry Smith```
306*4bcd95a3SBarry Smithtypedef struct _PetscObjectList* PetscObjectList;
307*4bcd95a3SBarry Smithstruct _PetscObjectList {
308*4bcd95a3SBarry Smith    char             name[128];
309*4bcd95a3SBarry Smith    PetscObject      obj;
310*4bcd95a3SBarry Smith    PetscObjectList  next;
311*4bcd95a3SBarry Smith};
312*4bcd95a3SBarry Smith```
313*4bcd95a3SBarry Smith
314*4bcd95a3SBarry Smithfrom which linked lists of composed objects may be constructed. The
315*4bcd95a3SBarry Smithroutines to manipulate these elementary objects are
316*4bcd95a3SBarry Smith
317*4bcd95a3SBarry Smith```
318*4bcd95a3SBarry Smithint PetscObjectListAdd(PetscObjectList *fl,const char *name,PetscObject obj);
319*4bcd95a3SBarry Smithint PetscObjectListDestroy(PetscObjectList *fl);
320*4bcd95a3SBarry Smithint PetscObjectListFind(PetscObjectList fl,const char *name,PetscObject *obj)
321*4bcd95a3SBarry Smithint PetscObjectListDuplicate(PetscObjectList fl,PetscObjectList *nl);
322*4bcd95a3SBarry Smith```
323*4bcd95a3SBarry Smith
324*4bcd95a3SBarry SmithThe function `PetscObjectListAdd()` will create the initial
325*4bcd95a3SBarry SmithPetscObjectList if the argument `fl` points to a NULL.
326*4bcd95a3SBarry Smith
327*4bcd95a3SBarry SmithThe PETSc object `compose()` and `query()` functions are as follows
328*4bcd95a3SBarry Smith(defined in
329*4bcd95a3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/sys/objects/inherit.c.html">src/sys/objects/inherit.c</a>
330*4bcd95a3SBarry Smith
331*4bcd95a3SBarry Smith```
332*4bcd95a3SBarry SmithPetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char *name,PetscObject ptr)
333*4bcd95a3SBarry Smith{
334*4bcd95a3SBarry Smith  PetscFunctionBegin;
335*4bcd95a3SBarry Smith  PetscCall(PetscObjectListAdd(&obj->olist,name,ptr));
336*4bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
337*4bcd95a3SBarry Smith}
338*4bcd95a3SBarry Smith
339*4bcd95a3SBarry SmithPetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char *name,PetscObject *ptr)
340*4bcd95a3SBarry Smith{
341*4bcd95a3SBarry Smith  PetscFunctionBegin;
342*4bcd95a3SBarry Smith  PetscCall(PetscObjectListFind(obj->olist,name,ptr));
343*4bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
344*4bcd95a3SBarry Smith}
345*4bcd95a3SBarry Smith```
346*4bcd95a3SBarry Smith
347*4bcd95a3SBarry Smith### Compose and Query Functions
348*4bcd95a3SBarry Smith
349*4bcd95a3SBarry SmithPETSc allows you to compose functions by specifying a name and function
350*4bcd95a3SBarry Smithpointer. In
351*4bcd95a3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/sys/dll/reg.c.html">src/sys/dll/reg.c</a>
352*4bcd95a3SBarry SmithPETSc defines the following linked list structure.
353*4bcd95a3SBarry Smith
354*4bcd95a3SBarry Smith```
355*4bcd95a3SBarry Smithstruct _n_PetscFunctionList {
356*4bcd95a3SBarry Smith  void              (*routine)(void);    /* the routine */
357*4bcd95a3SBarry Smith  char              *name;               /* string to identify routine */
358*4bcd95a3SBarry Smith  PetscFunctionList next;                /* next pointer */
359*4bcd95a3SBarry Smith  PetscFunctionList next_list;           /* used to maintain list of all lists for freeing */
360*4bcd95a3SBarry Smith};
361*4bcd95a3SBarry Smith```
362*4bcd95a3SBarry Smith
363*4bcd95a3SBarry SmithEach PETSc object contains a `PetscFunctionList` object. The
364*4bcd95a3SBarry Smith`composefunction()` and `queryfunction()` are given by the
365*4bcd95a3SBarry Smithfollowing.
366*4bcd95a3SBarry Smith
367*4bcd95a3SBarry Smith```
368*4bcd95a3SBarry SmithPetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char *name,void *ptr)
369*4bcd95a3SBarry Smith{
370*4bcd95a3SBarry Smith  PetscFunctionBegin;
371*4bcd95a3SBarry Smith  PetscCall(PetscFunctionListAdd(&obj->qlist,name,fname,ptr));
372*4bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
373*4bcd95a3SBarry Smith}
374*4bcd95a3SBarry Smith
375*4bcd95a3SBarry SmithPetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char *name,void (**ptr)(void))
376*4bcd95a3SBarry Smith{
377*4bcd95a3SBarry Smith  PetscFunctionBegin;
378*4bcd95a3SBarry Smith  PetscCall(PetscFunctionListFind(obj->qlist,name,ptr));
379*4bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
380*4bcd95a3SBarry Smith}
381*4bcd95a3SBarry Smith```
382*4bcd95a3SBarry Smith
383*4bcd95a3SBarry SmithIn addition to using the `PetscFunctionList` mechanism to compose
384*4bcd95a3SBarry Smithfunctions into PETSc objects, it is also used to allow registration of
385*4bcd95a3SBarry Smithnew class implementations; for example, new preconditioners.
386*4bcd95a3SBarry Smith
387*4bcd95a3SBarry SmithPETSc code that calls composed functions should be done via
388*4bcd95a3SBarry Smith
389*4bcd95a3SBarry Smith```
390*4bcd95a3SBarry SmithPetscUseMethod(obj,"method",(Argument types),(argument variables));
391*4bcd95a3SBarry SmithPetscTryMethod(obj,"method",(Argument types),(argument variables));
392*4bcd95a3SBarry Smith```
393*4bcd95a3SBarry Smith
394*4bcd95a3SBarry SmithFor example,
395*4bcd95a3SBarry Smith
396*4bcd95a3SBarry Smith```
397*4bcd95a3SBarry SmithPetscErrorCode  KSPGMRESSetRestart(KSP ksp, PetscInt restart)
398*4bcd95a3SBarry Smith{
399*4bcd95a3SBarry Smith  PetscFunctionBegin;
400*4bcd95a3SBarry Smith  PetscValidLogicalCollectiveInt(ksp,restart,2);
401*4bcd95a3SBarry Smith
402*4bcd95a3SBarry Smith  PetscTryMethod(ksp,"KSPGMRESSetRestart_C",(KSP,PetscInt),(ksp,restart));
403*4bcd95a3SBarry Smith  PetscFunctionReturn(PETSC_SUCCESS);
404*4bcd95a3SBarry Smith}
405*4bcd95a3SBarry Smith```
406*4bcd95a3SBarry Smith
407*4bcd95a3SBarry SmithThe `Try` variant skips the function call if the method has not been composed with
408*4bcd95a3SBarry Smiththe object while the `Use` version generates an error in that case.
409*4bcd95a3SBarry SmithSee also, `PetscUseTypeMethod()`, and `PetscTryTypeMethod()`.
410*4bcd95a3SBarry Smith
411*4bcd95a3SBarry Smith### Simple PETSc Objects
412*4bcd95a3SBarry Smith
413*4bcd95a3SBarry SmithSome simple PETSc objects do not need `PETSCHEADER` and the associated
414*4bcd95a3SBarry Smithfunctionality. These objects are internally named as `_n_<class>` as
415*4bcd95a3SBarry Smithopposed to `_p_<class>`, for example, `_n_PetscFunctionList` vs `_p_Vec`.
416*4bcd95a3SBarry Smith
417*4bcd95a3SBarry Smith## PETSc Packages
418*4bcd95a3SBarry Smith
419*4bcd95a3SBarry SmithThe PETSc source code is divided into the following library-level
420*4bcd95a3SBarry Smithpackages: `Sys`, `Vec`, `Mat`, `DM`, `KSP`, `SNES`, `TS`,
421*4bcd95a3SBarry Smith`Tao`. Each of these has a directory under the `src` directory in
422*4bcd95a3SBarry Smiththe PETSc tree and, optionally, can be compiled into separate libraries.
423*4bcd95a3SBarry SmithEach package defines one or more classes; for example, the `KSP`
424*4bcd95a3SBarry Smithpackage defines the `KSP` and `PC` classes, as well as several
425*4bcd95a3SBarry Smithutility classes. In addition, each library-level package may contain
426*4bcd95a3SBarry Smithseveral class-level packages associated with individual classes in the
427*4bcd95a3SBarry Smithlibrary-level package. In general, most “important” classes in PETSc
428*4bcd95a3SBarry Smithhave their own class level package. Each package provides a registration
429*4bcd95a3SBarry Smithfunction `XXXInitializePackage()`, for example
430*4bcd95a3SBarry Smith`KSPInitializePackage()`, which registers all the classes and events
431*4bcd95a3SBarry Smithfor that package. Each package also registers a finalization routine,
432*4bcd95a3SBarry Smith`XXXFinalizePackage()`, that releases all the resources used in
433*4bcd95a3SBarry Smithregistering the package, using `PetscRegisterFinalize()`. The
434*4bcd95a3SBarry Smithregistration for each package is performed “on demand” the first time a
435*4bcd95a3SBarry Smithclass in the package is utilized. This is handled, for example, with
436*4bcd95a3SBarry Smithcode such as
437*4bcd95a3SBarry Smith
438*4bcd95a3SBarry Smith```
439*4bcd95a3SBarry SmithPetscErrorCode  VecCreate(MPI_Comm comm, Vec *vec)
440*4bcd95a3SBarry Smith{
441*4bcd95a3SBarry Smith  Vec            v;
442*4bcd95a3SBarry Smith
443*4bcd95a3SBarry Smith  PetscFunctionBegin;
444*4bcd95a3SBarry Smith  PetscAssertPointer(vec,2);
445*4bcd95a3SBarry Smith  *vec = NULL;
446*4bcd95a3SBarry Smith  VecInitializePackage();
447*4bcd95a3SBarry Smith  ...
448*4bcd95a3SBarry Smith```
449