xref: /petsc/src/sys/dll/reg.c (revision 22b6d1ca80e4f79123036fb6afd7eb4463b3692a)
17d0a6c19SBarry Smith 
2e5c89e4eSSatish Balay /*
3e5c89e4eSSatish Balay     Provides a general mechanism to allow one to register new routines in
4e5c89e4eSSatish Balay     dynamic libraries for many of the PETSc objects (including, e.g., KSP and PC).
5e5c89e4eSSatish Balay */
6afcb2eb5SJed Brown #include <petsc-private/petscimpl.h>           /*I "petscsys.h" I*/
7665c2dedSJed Brown #include <petscviewer.h>
8e5c89e4eSSatish Balay 
93fa76a5bSLisandro Dalcin /*
103fa76a5bSLisandro Dalcin     This is the default list used by PETSc with the PetscDLLibrary register routines
113fa76a5bSLisandro Dalcin */
12d44a1e48SBarry Smith PetscDLLibrary PetscDLLibrariesLoaded = 0;
133fa76a5bSLisandro Dalcin 
14aa2d57e9SJed Brown #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
15ebd79076SLisandro Dalcin 
16e5c89e4eSSatish Balay #undef __FUNCT__
17487e5849SBarry Smith #define __FUNCT__ "PetscLoadDynamicLibrary"
187087cfbeSBarry Smith static PetscErrorCode  PetscLoadDynamicLibrary(const char *name,PetscBool  *found)
19487e5849SBarry Smith {
20487e5849SBarry Smith   char           libs[PETSC_MAX_PATH_LEN],dlib[PETSC_MAX_PATH_LEN];
21487e5849SBarry Smith   PetscErrorCode ierr;
22487e5849SBarry Smith 
23487e5849SBarry Smith   PetscFunctionBegin;
24487e5849SBarry Smith   ierr = PetscStrcpy(libs,"${PETSC_LIB_DIR}/libpetsc");CHKERRQ(ierr);
25487e5849SBarry Smith   ierr = PetscStrcat(libs,name);CHKERRQ(ierr);
26487e5849SBarry Smith   ierr = PetscDLLibraryRetrieve(PETSC_COMM_WORLD,libs,dlib,1024,found);CHKERRQ(ierr);
27487e5849SBarry Smith   if (*found) {
28d44a1e48SBarry Smith     ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,dlib);CHKERRQ(ierr);
29487e5849SBarry Smith   } else {
30487e5849SBarry Smith     ierr = PetscStrcpy(libs,"${PETSC_DIR}/${PETSC_ARCH}/lib/libpetsc");CHKERRQ(ierr);
31487e5849SBarry Smith     ierr = PetscStrcat(libs,name);CHKERRQ(ierr);
32487e5849SBarry Smith     ierr = PetscDLLibraryRetrieve(PETSC_COMM_WORLD,libs,dlib,1024,found);CHKERRQ(ierr);
33487e5849SBarry Smith     if (*found) {
34d44a1e48SBarry Smith       ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,dlib);CHKERRQ(ierr);
35487e5849SBarry Smith     }
36487e5849SBarry Smith   }
37487e5849SBarry Smith   PetscFunctionReturn(0);
38487e5849SBarry Smith }
39487e5849SBarry Smith 
403fa76a5bSLisandro Dalcin #endif
413fa76a5bSLisandro Dalcin 
42acff04ddSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY)
43*22b6d1caSBarry Smith #include <petscthreadcomm.h>
44*22b6d1caSBarry Smith extern PetscErrorCode PetscThreadCommWorldInitialize(void);
45*22b6d1caSBarry Smith extern PetscErrorCode AOInitializePackage(void);
46*22b6d1caSBarry Smith extern PetscErrorCode PetscSFInitializePackage(void);
47*22b6d1caSBarry Smith extern PetscErrorCode CharacteristicInitializePackage(void);
48*22b6d1caSBarry Smith extern PetscErrorCode ISInitializePackage(void);
49*22b6d1caSBarry Smith extern PetscErrorCode VecInitializePackage(void);
50*22b6d1caSBarry Smith extern PetscErrorCode MatInitializePackage(void);
51*22b6d1caSBarry Smith extern PetscErrorCode DMInitializePackage(void);
52*22b6d1caSBarry Smith extern PetscErrorCode PCInitializePackage(void);
53*22b6d1caSBarry Smith extern PetscErrorCode KSPInitializePackage(void);
54*22b6d1caSBarry Smith extern PetscErrorCode SNESInitializePackage(void);
55*22b6d1caSBarry Smith extern PetscErrorCode TSInitializePackage(void);
56*22b6d1caSBarry Smith static MPI_Comm PETSC_COMM_WORLD_INNER = 0,PETSC_COMM_SELF_INNER = 0;
57acff04ddSBarry Smith #endif
58acff04ddSBarry Smith 
59487e5849SBarry Smith #undef __FUNCT__
60e5c89e4eSSatish Balay #define __FUNCT__ "PetscInitialize_DynamicLibraries"
61e5c89e4eSSatish Balay /*
62e5c89e4eSSatish Balay     PetscInitialize_DynamicLibraries - Adds the default dynamic link libraries to the
63e5c89e4eSSatish Balay     search path.
64e5c89e4eSSatish Balay */
657087cfbeSBarry Smith PetscErrorCode  PetscInitialize_DynamicLibraries(void)
66e5c89e4eSSatish Balay {
67487e5849SBarry Smith   char           *libname[32];
68e5c89e4eSSatish Balay   PetscErrorCode ierr;
69e5c89e4eSSatish Balay   PetscInt       nmax,i;
70aa2d57e9SJed Brown #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
71aa2d57e9SJed Brown   PetscBool      preload;
723fa76a5bSLisandro Dalcin #endif
73e5c89e4eSSatish Balay 
7460154eb2SBarry Smith   PetscFunctionBegin;
75e5c89e4eSSatish Balay   nmax = 32;
760298fd71SBarry Smith   ierr = PetscOptionsGetStringArray(NULL,"-dll_prepend",libname,&nmax,NULL);CHKERRQ(ierr);
77e5c89e4eSSatish Balay   for (i=0; i<nmax; i++) {
78d44a1e48SBarry Smith     ierr = PetscDLLibraryPrepend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,libname[i]);CHKERRQ(ierr);
79e5c89e4eSSatish Balay     ierr = PetscFree(libname[i]);CHKERRQ(ierr);
80e5c89e4eSSatish Balay   }
81e5c89e4eSSatish Balay 
82aa2d57e9SJed Brown #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
833fa76a5bSLisandro Dalcin   /*
843fa76a5bSLisandro Dalcin       This just initializes the most basic PETSc stuff.
853fa76a5bSLisandro Dalcin 
863fa76a5bSLisandro Dalcin     The classes, from PetscDraw to PetscTS, are initialized the first
873fa76a5bSLisandro Dalcin     time an XXCreate() is called.
883fa76a5bSLisandro Dalcin   */
89607a6623SBarry Smith   ierr = PetscSysInitializePackage();CHKERRQ(ierr);
903fa76a5bSLisandro Dalcin #else
91aa2d57e9SJed Brown   preload = PETSC_FALSE;
92aa2d57e9SJed Brown   ierr = PetscOptionsGetBool(NULL,"-dynamic_library_preload",&preload,NULL);CHKERRQ(ierr);
93aa2d57e9SJed Brown   if (preload) {
94aa2d57e9SJed Brown     PetscBool found;
9560154eb2SBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY)
96487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("",&found);CHKERRQ(ierr);
97e32f2f54SBarry Smith     if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!");
9860154eb2SBarry Smith #else
9960154eb2SBarry Smith     ierr = PetscLoadDynamicLibrary("sys",&found);CHKERRQ(ierr);
10060154eb2SBarry Smith     if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!");
101487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("vec",&found);CHKERRQ(ierr);
102e32f2f54SBarry Smith     if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc Vec dynamic library \n You cannot move the dynamic libraries!");
103487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("mat",&found);CHKERRQ(ierr);
104e32f2f54SBarry Smith     if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc Mat dynamic library \n You cannot move the dynamic libraries!");
105487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("dm",&found);CHKERRQ(ierr);
106e32f2f54SBarry Smith     if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc DM dynamic library \n You cannot move the dynamic libraries!");
107487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("ksp",&found);CHKERRQ(ierr);
108e32f2f54SBarry Smith     if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc KSP dynamic library \n You cannot move the dynamic libraries!");
109487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("snes",&found);CHKERRQ(ierr);
110e32f2f54SBarry Smith     if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc SNES dynamic library \n You cannot move the dynamic libraries!");
111487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("ts",&found);CHKERRQ(ierr);
112e32f2f54SBarry Smith     if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc TS dynamic library \n You cannot move the dynamic libraries!");
113bb84e0fdSBarry Smith #endif
114aa2d57e9SJed Brown   }
1153fa76a5bSLisandro Dalcin #endif
116e5c89e4eSSatish Balay 
117e5c89e4eSSatish Balay   nmax = 32;
1180298fd71SBarry Smith   ierr = PetscOptionsGetStringArray(NULL,"-dll_append",libname,&nmax,NULL);CHKERRQ(ierr);
119e5c89e4eSSatish Balay   for (i=0; i<nmax; i++) {
120d44a1e48SBarry Smith     ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,libname[i]);CHKERRQ(ierr);
121e5c89e4eSSatish Balay     ierr = PetscFree(libname[i]);CHKERRQ(ierr);
122e5c89e4eSSatish Balay   }
1233020f62cSBarry Smith 
124acff04ddSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY)
125*22b6d1caSBarry Smith   /* These must be done here because it is not safe for individual threads to call these initialize routines */
1263020f62cSBarry Smith   ierr = PetscThreadCommInitializePackage();CHKERRQ(ierr);
1273020f62cSBarry Smith   ierr = PetscThreadCommWorldInitialize();CHKERRQ(ierr);
1283020f62cSBarry Smith   ierr = AOInitializePackage();CHKERRQ(ierr);
1293020f62cSBarry Smith   ierr = PetscSFInitializePackage();CHKERRQ(ierr);
1303020f62cSBarry Smith   ierr = CharacteristicInitializePackage();CHKERRQ(ierr);
1313020f62cSBarry Smith   ierr = ISInitializePackage();CHKERRQ(ierr);
1323020f62cSBarry Smith   ierr = VecInitializePackage();CHKERRQ(ierr);
1333020f62cSBarry Smith   ierr = MatInitializePackage();CHKERRQ(ierr);
1343020f62cSBarry Smith   ierr = DMInitializePackage();CHKERRQ(ierr);
1353020f62cSBarry Smith   ierr = PCInitializePackage();CHKERRQ(ierr);
1363020f62cSBarry Smith   ierr = KSPInitializePackage();CHKERRQ(ierr);
1373020f62cSBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
1383020f62cSBarry Smith   ierr = TSInitializePackage();CHKERRQ(ierr);
139acff04ddSBarry Smith   ierr = PetscCommDuplicate(PETSC_COMM_SELF,&PETSC_COMM_SELF_INNER,NULL);CHKERRQ(ierr);
140acff04ddSBarry Smith   ierr = PetscCommDuplicate(PETSC_COMM_WORLD,&PETSC_COMM_WORLD_INNER,NULL);CHKERRQ(ierr);
141acff04ddSBarry Smith #endif
142e5c89e4eSSatish Balay   PetscFunctionReturn(0);
143e5c89e4eSSatish Balay }
144e5c89e4eSSatish Balay 
145e5c89e4eSSatish Balay #undef __FUNCT__
146e5c89e4eSSatish Balay #define __FUNCT__ "PetscFinalize_DynamicLibraries"
147ebd79076SLisandro Dalcin /*
148ebd79076SLisandro Dalcin      PetscFinalize_DynamicLibraries - Closes the opened dynamic libraries.
149ebd79076SLisandro Dalcin */
150e5c89e4eSSatish Balay PetscErrorCode PetscFinalize_DynamicLibraries(void)
151e5c89e4eSSatish Balay {
152ebd79076SLisandro Dalcin   PetscErrorCode ierr;
153ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
154e5c89e4eSSatish Balay 
155ebd79076SLisandro Dalcin   PetscFunctionBegin;
1560298fd71SBarry Smith   ierr = PetscOptionsGetBool(NULL,"-dll_view",&flg,NULL);CHKERRQ(ierr);
157d44a1e48SBarry Smith   if (flg) { ierr = PetscDLLibraryPrintPath(PetscDLLibrariesLoaded);CHKERRQ(ierr); }
158d44a1e48SBarry Smith   ierr = PetscDLLibraryClose(PetscDLLibrariesLoaded);CHKERRQ(ierr);
159a297a907SKarl Rupp 
160acff04ddSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY)
161acff04ddSBarry Smith   ierr = PetscCommDestroy(&PETSC_COMM_SELF_INNER);CHKERRQ(ierr);
162acff04ddSBarry Smith   ierr = PetscCommDestroy(&PETSC_COMM_WORLD_INNER);CHKERRQ(ierr);
163acff04ddSBarry Smith #endif
164acff04ddSBarry Smith 
165d44a1e48SBarry Smith   PetscDLLibrariesLoaded = 0;
166e5c89e4eSSatish Balay   PetscFunctionReturn(0);
167e5c89e4eSSatish Balay }
168e5c89e4eSSatish Balay 
169e4d1774bSDmitry Karpeev 
170e4d1774bSDmitry Karpeev 
171e5c89e4eSSatish Balay /* ------------------------------------------------------------------------------*/
172140e18c1SBarry Smith struct _n_PetscFunctionList {
173e5c89e4eSSatish Balay   void              (*routine)(void);    /* the routine */
174e5c89e4eSSatish Balay   char              *name;               /* string to identify routine */
175140e18c1SBarry Smith   PetscFunctionList next;                /* next pointer */
176140e18c1SBarry Smith   PetscFunctionList next_list;           /* used to maintain list of all lists for freeing */
177e5c89e4eSSatish Balay };
178e5c89e4eSSatish Balay 
179e5c89e4eSSatish Balay /*
180140e18c1SBarry Smith      Keep a linked list of PetscFunctionLists so that we can destroy all the left-over ones.
181e5c89e4eSSatish Balay */
182140e18c1SBarry Smith static PetscFunctionList dlallhead = 0;
183e5c89e4eSSatish Balay 
184a240a19fSJed Brown /*MC
185140e18c1SBarry Smith    PetscFunctionListAdd - Given a routine and a string id, saves that routine in the
186e5c89e4eSSatish Balay    specified registry.
187e5c89e4eSSatish Balay 
188a240a19fSJed Brown    Synopsis:
189aaa7dc30SBarry Smith    #include <petscsys.h>
190a240a19fSJed Brown    PetscErrorCode PetscFunctionListAdd(PetscFunctionList flist,const char name[],void (*fptr)(void))
191a240a19fSJed Brown 
192d4349b43SBarry Smith    Not Collective
193e5c89e4eSSatish Balay 
194e5c89e4eSSatish Balay    Input Parameters:
195a240a19fSJed Brown +  flist - pointer registry
196e5c89e4eSSatish Balay .  name - string to identify routine
197a240a19fSJed Brown -  fptr - function pointer
198e5c89e4eSSatish Balay 
199e5c89e4eSSatish Balay    Notes:
200a240a19fSJed Brown    To remove a registered routine, pass in a NULL fptr.
201e5c89e4eSSatish Balay 
202e5c89e4eSSatish Balay    Users who wish to register new classes for use by a particular PETSc
203e5c89e4eSSatish Balay    component (e.g., SNES) should generally call the registration routine
2041c84c290SBarry Smith    for that particular component (e.g., SNESRegister()) instead of
205140e18c1SBarry Smith    calling PetscFunctionListAdd() directly.
206e5c89e4eSSatish Balay 
207e5c89e4eSSatish Balay     Level: developer
208e5c89e4eSSatish Balay 
2091c84c290SBarry Smith .seealso: PetscFunctionListDestroy(), SNESRegister(), KSPRegister(),
210a240a19fSJed Brown           PCRegister(), TSRegister(), PetscFunctionList, PetscObjectComposeFunction()
211a240a19fSJed Brown M*/
212a240a19fSJed Brown #undef __FUNCT__
213a240a19fSJed Brown #define __FUNCT__ "PetscFunctionListAdd_Private"
214a240a19fSJed Brown PETSC_EXTERN PetscErrorCode PetscFunctionListAdd_Private(PetscFunctionList *fl,const char name[],void (*fnc)(void))
215e5c89e4eSSatish Balay {
216140e18c1SBarry Smith   PetscFunctionList entry,ne;
217e5c89e4eSSatish Balay   PetscErrorCode    ierr;
218e5c89e4eSSatish Balay 
219e5c89e4eSSatish Balay   PetscFunctionBegin;
220e5c89e4eSSatish Balay   if (!*fl) {
221b00a9115SJed Brown     ierr           = PetscNew(&entry);CHKERRQ(ierr);
222e5c89e4eSSatish Balay     ierr           = PetscStrallocpy(name,&entry->name);CHKERRQ(ierr);
223e5c89e4eSSatish Balay     entry->routine = fnc;
224e5c89e4eSSatish Balay     entry->next    = 0;
225e5c89e4eSSatish Balay     *fl            = entry;
226e5c89e4eSSatish Balay 
227a8a6328fSBarry Smith #if defined(PETSC_USE_LOG)
228e5c89e4eSSatish Balay     /* add this new list to list of all lists */
229e5c89e4eSSatish Balay     if (!dlallhead) {
230e5c89e4eSSatish Balay       dlallhead        = *fl;
231e5c89e4eSSatish Balay       (*fl)->next_list = 0;
232e5c89e4eSSatish Balay     } else {
233e5c89e4eSSatish Balay       ne               = dlallhead;
234e5c89e4eSSatish Balay       dlallhead        = *fl;
235e5c89e4eSSatish Balay       (*fl)->next_list = ne;
236e5c89e4eSSatish Balay     }
237a8a6328fSBarry Smith #endif
238a8a6328fSBarry Smith 
239e5c89e4eSSatish Balay   } else {
240e5c89e4eSSatish Balay     /* search list to see if it is already there */
241e5c89e4eSSatish Balay     ne = *fl;
242e5c89e4eSSatish Balay     while (ne) {
243ace3abfcSBarry Smith       PetscBool founddup;
244e5c89e4eSSatish Balay 
245e5c89e4eSSatish Balay       ierr = PetscStrcmp(ne->name,name,&founddup);CHKERRQ(ierr);
246e5c89e4eSSatish Balay       if (founddup) { /* found duplicate */
247e5c89e4eSSatish Balay         ne->routine = fnc;
248e5c89e4eSSatish Balay         PetscFunctionReturn(0);
249e5c89e4eSSatish Balay       }
250a297a907SKarl Rupp       if (ne->next) ne = ne->next;
251a297a907SKarl Rupp       else break;
252e5c89e4eSSatish Balay     }
253e5c89e4eSSatish Balay     /* create new entry and add to end of list */
254b00a9115SJed Brown     ierr           = PetscNew(&entry);CHKERRQ(ierr);
255e5c89e4eSSatish Balay     ierr           = PetscStrallocpy(name,&entry->name);CHKERRQ(ierr);
256e5c89e4eSSatish Balay     entry->routine = fnc;
257e5c89e4eSSatish Balay     entry->next    = 0;
258e5c89e4eSSatish Balay     ne->next       = entry;
259e5c89e4eSSatish Balay   }
260e5c89e4eSSatish Balay   PetscFunctionReturn(0);
261e5c89e4eSSatish Balay }
262e5c89e4eSSatish Balay 
263e5c89e4eSSatish Balay #undef __FUNCT__
264140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListDestroy"
265e5c89e4eSSatish Balay /*@
266140e18c1SBarry Smith     PetscFunctionListDestroy - Destroys a list of registered routines.
267e5c89e4eSSatish Balay 
268e5c89e4eSSatish Balay     Input Parameter:
269e5c89e4eSSatish Balay .   fl  - pointer to list
270e5c89e4eSSatish Balay 
271e5c89e4eSSatish Balay     Level: developer
272e5c89e4eSSatish Balay 
273a240a19fSJed Brown .seealso: PetscFunctionListAdd(), PetscFunctionList
274e5c89e4eSSatish Balay @*/
275140e18c1SBarry Smith PetscErrorCode  PetscFunctionListDestroy(PetscFunctionList *fl)
276e5c89e4eSSatish Balay {
277140e18c1SBarry Smith   PetscFunctionList next,entry,tmp = dlallhead;
278e5c89e4eSSatish Balay   PetscErrorCode    ierr;
279e5c89e4eSSatish Balay 
280e5c89e4eSSatish Balay   PetscFunctionBegin;
2811441b1d3SBarry Smith   if (!*fl) PetscFunctionReturn(0);
282e5c89e4eSSatish Balay 
283e5c89e4eSSatish Balay   /*
284e5c89e4eSSatish Balay        Remove this entry from the master DL list (if it is in it)
285e5c89e4eSSatish Balay   */
2861441b1d3SBarry Smith   if (dlallhead == *fl) {
287a297a907SKarl Rupp     if (dlallhead->next_list) dlallhead = dlallhead->next_list;
28837e93019SBarry Smith     else dlallhead = NULL;
28937e93019SBarry Smith   } else if (tmp) {
2901441b1d3SBarry Smith     while (tmp->next_list != *fl) {
291e5c89e4eSSatish Balay       tmp = tmp->next_list;
292e5c89e4eSSatish Balay       if (!tmp->next_list) break;
293e5c89e4eSSatish Balay     }
294e5c89e4eSSatish Balay     if (tmp->next_list) tmp->next_list = tmp->next_list->next_list;
295e5c89e4eSSatish Balay   }
296e5c89e4eSSatish Balay 
297e5c89e4eSSatish Balay   /* free this list */
2981441b1d3SBarry Smith   entry = *fl;
299e5c89e4eSSatish Balay   while (entry) {
300e5c89e4eSSatish Balay     next  = entry->next;
301e5c89e4eSSatish Balay     ierr  = PetscFree(entry->name);CHKERRQ(ierr);
302e5c89e4eSSatish Balay     ierr  = PetscFree(entry);CHKERRQ(ierr);
303e5c89e4eSSatish Balay     entry = next;
304e5c89e4eSSatish Balay   }
3051441b1d3SBarry Smith   *fl = 0;
306e5c89e4eSSatish Balay   PetscFunctionReturn(0);
307e5c89e4eSSatish Balay }
308e5c89e4eSSatish Balay 
309e5c89e4eSSatish Balay /*
31037e93019SBarry Smith    Print any PetscFunctionLists that have not be destroyed
311e5c89e4eSSatish Balay */
312e5c89e4eSSatish Balay #undef __FUNCT__
31337e93019SBarry Smith #define __FUNCT__ "PetscFunctionListPrintAll"
31437e93019SBarry Smith PetscErrorCode  PetscFunctionListPrintAll(void)
315e5c89e4eSSatish Balay {
31637e93019SBarry Smith   PetscFunctionList tmp = dlallhead;
317e5c89e4eSSatish Balay   PetscErrorCode    ierr;
318e5c89e4eSSatish Balay 
319e5c89e4eSSatish Balay   PetscFunctionBegin;
32037e93019SBarry Smith   if (tmp) {
32137e93019SBarry Smith     ierr = PetscPrintf(PETSC_COMM_WORLD,"The following PetscFunctionLists were not destroyed\n");CHKERRQ(ierr);
322e5c89e4eSSatish Balay   }
32337e93019SBarry Smith   while (tmp) {
32437e93019SBarry Smith     ierr = PetscPrintf(PETSC_COMM_WORLD,"%s \n",tmp->name);CHKERRQ(ierr);
32537e93019SBarry Smith     tmp = tmp->next_list;
32637e93019SBarry Smith   }
327e5c89e4eSSatish Balay   PetscFunctionReturn(0);
328e5c89e4eSSatish Balay }
329e5c89e4eSSatish Balay 
3301c9cd337SJed Brown /*MC
3311c9cd337SJed Brown     PetscFunctionListFind - Find function registered under given name
3321c9cd337SJed Brown 
3331c9cd337SJed Brown     Synopsis:
334aaa7dc30SBarry Smith     #include <petscsys.h>
3351c9cd337SJed Brown     PetscErrorCode PetscFunctionListFind(PetscFunctionList flist,const char name[],void (**fptr)(void))
336e5c89e4eSSatish Balay 
337e5c89e4eSSatish Balay     Input Parameters:
3381c9cd337SJed Brown +   flist   - pointer to list
3391c9cd337SJed Brown -   name - name registered for the function
340e5c89e4eSSatish Balay 
341e5c89e4eSSatish Balay     Output Parameters:
3421c9cd337SJed Brown .   fptr - the function pointer if name was found, else NULL
343e5c89e4eSSatish Balay 
344e5c89e4eSSatish Balay     Level: developer
345e5c89e4eSSatish Balay 
3461c9cd337SJed Brown .seealso: PetscFunctionListAdd(), PetscFunctionList, PetscObjectQueryFunction()
3471c9cd337SJed Brown M*/
3481c9cd337SJed Brown #undef __FUNCT__
3491c9cd337SJed Brown #define __FUNCT__ "PetscFunctionListFind_Private"
3501c9cd337SJed Brown PETSC_EXTERN PetscErrorCode PetscFunctionListFind_Private(PetscFunctionList fl,const char name[],void (**r)(void))
351e5c89e4eSSatish Balay {
352140e18c1SBarry Smith   PetscFunctionList entry = fl;
353e5c89e4eSSatish Balay   PetscErrorCode    ierr;
354bdf89e91SBarry Smith   PetscBool         flg;
355e5c89e4eSSatish Balay 
356e5c89e4eSSatish Balay   PetscFunctionBegin;
357e32f2f54SBarry Smith   if (!name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to find routine with null name");
358e5c89e4eSSatish Balay 
359e5c89e4eSSatish Balay   *r = 0;
360e5c89e4eSSatish Balay   while (entry) {
361bdf89e91SBarry Smith     ierr = PetscStrcmp(name,entry->name,&flg);CHKERRQ(ierr);
362bdf89e91SBarry Smith     if (flg) {
363e5c89e4eSSatish Balay       *r   = entry->routine;
364e5c89e4eSSatish Balay       PetscFunctionReturn(0);
365e5c89e4eSSatish Balay     }
366e5c89e4eSSatish Balay     entry = entry->next;
367e5c89e4eSSatish Balay   }
368e5c89e4eSSatish Balay   PetscFunctionReturn(0);
369e5c89e4eSSatish Balay }
370e5c89e4eSSatish Balay 
371e5c89e4eSSatish Balay #undef __FUNCT__
372140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListView"
373e5c89e4eSSatish Balay /*@
374140e18c1SBarry Smith    PetscFunctionListView - prints out contents of an PetscFunctionList
375e5c89e4eSSatish Balay 
376e5c89e4eSSatish Balay    Collective over MPI_Comm
377e5c89e4eSSatish Balay 
378e5c89e4eSSatish Balay    Input Parameters:
379e5c89e4eSSatish Balay +  list - the list of functions
380e5c89e4eSSatish Balay -  viewer - currently ignored
381e5c89e4eSSatish Balay 
382e5c89e4eSSatish Balay    Level: developer
383e5c89e4eSSatish Balay 
384a240a19fSJed Brown .seealso: PetscFunctionListAdd(), PetscFunctionListPrintTypes(), PetscFunctionList
385e5c89e4eSSatish Balay @*/
386140e18c1SBarry Smith PetscErrorCode  PetscFunctionListView(PetscFunctionList list,PetscViewer viewer)
387e5c89e4eSSatish Balay {
388e5c89e4eSSatish Balay   PetscErrorCode ierr;
389ace3abfcSBarry Smith   PetscBool      iascii;
390e5c89e4eSSatish Balay 
391e5c89e4eSSatish Balay   PetscFunctionBegin;
392e5c89e4eSSatish Balay   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
393e5c89e4eSSatish Balay   PetscValidPointer(list,1);
3940700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
395e5c89e4eSSatish Balay 
396251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
397e32f2f54SBarry Smith   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only ASCII viewer supported");
398e5c89e4eSSatish Balay 
399e5c89e4eSSatish Balay   while (list) {
400bdf89e91SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %s\n",list->name);CHKERRQ(ierr);
401e5c89e4eSSatish Balay     list = list->next;
402e5c89e4eSSatish Balay   }
403e5c89e4eSSatish Balay   ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
404e5c89e4eSSatish Balay   PetscFunctionReturn(0);
405e5c89e4eSSatish Balay }
406e5c89e4eSSatish Balay 
407e5c89e4eSSatish Balay #undef __FUNCT__
408140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListGet"
409065533a5SJed Brown /*@C
410140e18c1SBarry Smith    PetscFunctionListGet - Gets an array the contains the entries in PetscFunctionList, this is used
411e5c89e4eSSatish Balay          by help etc.
412e5c89e4eSSatish Balay 
413d4349b43SBarry Smith    Not Collective
414e5c89e4eSSatish Balay 
415e5c89e4eSSatish Balay    Input Parameter:
416e5c89e4eSSatish Balay .  list   - list of types
417e5c89e4eSSatish Balay 
418e5c89e4eSSatish Balay    Output Parameter:
419e5c89e4eSSatish Balay +  array - array of names
420e5c89e4eSSatish Balay -  n - length of array
421e5c89e4eSSatish Balay 
422e5c89e4eSSatish Balay    Notes:
423e5c89e4eSSatish Balay        This allocates the array so that must be freed. BUT the individual entries are
424e5c89e4eSSatish Balay     not copied so should not be freed.
425e5c89e4eSSatish Balay 
426e5c89e4eSSatish Balay    Level: developer
427e5c89e4eSSatish Balay 
428a240a19fSJed Brown .seealso: PetscFunctionListAdd(), PetscFunctionList
429e5c89e4eSSatish Balay @*/
430140e18c1SBarry Smith PetscErrorCode  PetscFunctionListGet(PetscFunctionList list,const char ***array,int *n)
431e5c89e4eSSatish Balay {
432e5c89e4eSSatish Balay   PetscErrorCode    ierr;
433e5c89e4eSSatish Balay   PetscInt          count = 0;
434140e18c1SBarry Smith   PetscFunctionList klist = list;
435e5c89e4eSSatish Balay 
436e5c89e4eSSatish Balay   PetscFunctionBegin;
437e5c89e4eSSatish Balay   while (list) {
438e5c89e4eSSatish Balay     list = list->next;
439e5c89e4eSSatish Balay     count++;
440e5c89e4eSSatish Balay   }
441854ce69bSBarry Smith   ierr  = PetscMalloc1(count+1,array);CHKERRQ(ierr);
442e5c89e4eSSatish Balay   count = 0;
443e5c89e4eSSatish Balay   while (klist) {
444e5c89e4eSSatish Balay     (*array)[count] = klist->name;
445e5c89e4eSSatish Balay     klist           = klist->next;
446e5c89e4eSSatish Balay     count++;
447e5c89e4eSSatish Balay   }
448e5c89e4eSSatish Balay   (*array)[count] = 0;
449e5c89e4eSSatish Balay   *n              = count+1;
450e5c89e4eSSatish Balay   PetscFunctionReturn(0);
451e5c89e4eSSatish Balay }
452e5c89e4eSSatish Balay 
453e5c89e4eSSatish Balay 
454e5c89e4eSSatish Balay #undef __FUNCT__
455140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListPrintTypes"
456e5c89e4eSSatish Balay /*@C
457140e18c1SBarry Smith    PetscFunctionListPrintTypes - Prints the methods available.
458e5c89e4eSSatish Balay 
459e5c89e4eSSatish Balay    Collective over MPI_Comm
460e5c89e4eSSatish Balay 
461e5c89e4eSSatish Balay    Input Parameters:
462e5c89e4eSSatish Balay +  comm   - the communicator (usually MPI_COMM_WORLD)
463e5c89e4eSSatish Balay .  fd     - file to print to, usually stdout
464e5c89e4eSSatish Balay .  prefix - prefix to prepend to name (optional)
465e5c89e4eSSatish Balay .  name   - option string (for example, "-ksp_type")
466e5c89e4eSSatish Balay .  text - short description of the object (for example, "Krylov solvers")
467e5c89e4eSSatish Balay .  man - name of manual page that discusses the object (for example, "KSPCreate")
4683cc1e11dSBarry Smith .  list   - list of types
4693cc1e11dSBarry Smith -  def - default (current) value
470e5c89e4eSSatish Balay 
471e5c89e4eSSatish Balay    Level: developer
472e5c89e4eSSatish Balay 
473a240a19fSJed Brown .seealso: PetscFunctionListAdd(), PetscFunctionList
474e5c89e4eSSatish Balay @*/
475140e18c1SBarry Smith PetscErrorCode  PetscFunctionListPrintTypes(MPI_Comm comm,FILE *fd,const char prefix[],const char name[],const char text[],const char man[],PetscFunctionList list,const char def[])
476e5c89e4eSSatish Balay {
477e5c89e4eSSatish Balay   PetscErrorCode ierr;
478e5c89e4eSSatish Balay   PetscInt       count = 0;
479e5c89e4eSSatish Balay   char           p[64];
480e5c89e4eSSatish Balay 
481e5c89e4eSSatish Balay   PetscFunctionBegin;
482da9f1d6bSBarry Smith   if (!fd) fd = PETSC_STDOUT;
483e5c89e4eSSatish Balay 
484e5c89e4eSSatish Balay   ierr = PetscStrcpy(p,"-");CHKERRQ(ierr);
485e5c89e4eSSatish Balay   if (prefix) {ierr = PetscStrcat(p,prefix);CHKERRQ(ierr);}
4863cc1e11dSBarry Smith   ierr = PetscFPrintf(comm,fd,"  %s%s <%s>: %s (one of)",p,name+1,def,text);CHKERRQ(ierr);
487e5c89e4eSSatish Balay 
488e5c89e4eSSatish Balay   while (list) {
489e5c89e4eSSatish Balay     ierr = PetscFPrintf(comm,fd," %s",list->name);CHKERRQ(ierr);
490e5c89e4eSSatish Balay     list = list->next;
491e5c89e4eSSatish Balay     count++;
492e5c89e4eSSatish Balay     if (count == 8) {ierr = PetscFPrintf(comm,fd,"\n     ");CHKERRQ(ierr);}
493e5c89e4eSSatish Balay   }
494e5c89e4eSSatish Balay   ierr = PetscFPrintf(comm,fd," (%s)\n",man);CHKERRQ(ierr);
495e5c89e4eSSatish Balay   PetscFunctionReturn(0);
496e5c89e4eSSatish Balay }
497e5c89e4eSSatish Balay 
498e5c89e4eSSatish Balay #undef __FUNCT__
499140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListDuplicate"
500e5c89e4eSSatish Balay /*@
501140e18c1SBarry Smith     PetscFunctionListDuplicate - Creates a new list from a given object list.
502e5c89e4eSSatish Balay 
503e5c89e4eSSatish Balay     Input Parameters:
504e5c89e4eSSatish Balay .   fl   - pointer to list
505e5c89e4eSSatish Balay 
506e5c89e4eSSatish Balay     Output Parameters:
507e5c89e4eSSatish Balay .   nl - the new list (should point to 0 to start, otherwise appends)
508e5c89e4eSSatish Balay 
509e5c89e4eSSatish Balay     Level: developer
510e5c89e4eSSatish Balay 
511140e18c1SBarry Smith .seealso: PetscFunctionList, PetscFunctionListAdd(), PetscFlistDestroy()
512e5c89e4eSSatish Balay 
513e5c89e4eSSatish Balay @*/
514140e18c1SBarry Smith PetscErrorCode  PetscFunctionListDuplicate(PetscFunctionList fl,PetscFunctionList *nl)
515e5c89e4eSSatish Balay {
516e5c89e4eSSatish Balay   PetscErrorCode ierr;
517e5c89e4eSSatish Balay 
518e5c89e4eSSatish Balay   PetscFunctionBegin;
519e5c89e4eSSatish Balay   while (fl) {
520bdf89e91SBarry Smith     ierr = PetscFunctionListAdd(nl,fl->name,fl->routine);CHKERRQ(ierr);
521e5c89e4eSSatish Balay     fl   = fl->next;
522e5c89e4eSSatish Balay   }
523e5c89e4eSSatish Balay   PetscFunctionReturn(0);
524e5c89e4eSSatish Balay }
525e5c89e4eSSatish Balay 
526