xref: /petsc/src/sys/dll/reg.c (revision 540e20f2dfe7523cd2ded23fbddbc37a2d1fd67c)
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 */
6af0996ceSBarry Smith #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 */
1202c9f0b5SLisandro Dalcin PetscDLLibrary PetscDLLibrariesLoaded = NULL;
133fa76a5bSLisandro Dalcin 
14cbd104e6SBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES)
15ebd79076SLisandro Dalcin 
16dc21ef1bSBarry Smith PetscErrorCode  PetscLoadDynamicLibrary(const char *name,PetscBool  *found)
17487e5849SBarry Smith {
18487e5849SBarry Smith   char           libs[PETSC_MAX_PATH_LEN],dlib[PETSC_MAX_PATH_LEN];
19487e5849SBarry Smith   PetscErrorCode ierr;
20487e5849SBarry Smith 
21487e5849SBarry Smith   PetscFunctionBegin;
22a126751eSBarry Smith   ierr = PetscStrncpy(libs,"${PETSC_LIB_DIR}/libpetsc",sizeof(libs));CHKERRQ(ierr);
23a126751eSBarry Smith   ierr = PetscStrlcat(libs,name,sizeof(libs));CHKERRQ(ierr);
24487e5849SBarry Smith   ierr = PetscDLLibraryRetrieve(PETSC_COMM_WORLD,libs,dlib,1024,found);CHKERRQ(ierr);
25487e5849SBarry Smith   if (*found) {
26d44a1e48SBarry Smith     ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,dlib);CHKERRQ(ierr);
27487e5849SBarry Smith   } else {
28a126751eSBarry Smith     ierr = PetscStrncpy(libs,"${PETSC_DIR}/${PETSC_ARCH}/lib/libpetsc",sizeof(libs));CHKERRQ(ierr);
29a126751eSBarry Smith     ierr = PetscStrlcat(libs,name,sizeof(libs));CHKERRQ(ierr);
30487e5849SBarry Smith     ierr = PetscDLLibraryRetrieve(PETSC_COMM_WORLD,libs,dlib,1024,found);CHKERRQ(ierr);
31487e5849SBarry Smith     if (*found) {
32d44a1e48SBarry Smith       ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,dlib);CHKERRQ(ierr);
33487e5849SBarry Smith     }
34487e5849SBarry Smith   }
35487e5849SBarry Smith   PetscFunctionReturn(0);
36487e5849SBarry Smith }
373fa76a5bSLisandro Dalcin #endif
383fa76a5bSLisandro Dalcin 
39acff04ddSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY)
4095c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode AOInitializePackage(void);
4195c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscSFInitializePackage(void);
427da51e29SSatish Balay #if !defined(PETSC_USE_COMPLEX)
4395c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode CharacteristicInitializePackage(void);
447da51e29SSatish Balay #endif
4595c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode ISInitializePackage(void);
4695c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode VecInitializePackage(void);
4795c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode MatInitializePackage(void);
4895c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode DMInitializePackage(void);
4995c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PCInitializePackage(void);
5095c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode KSPInitializePackage(void);
5195c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode SNESInitializePackage(void);
5295c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode TSInitializePackage(void);
5322b6d1caSBarry Smith static MPI_Comm PETSC_COMM_WORLD_INNER = 0,PETSC_COMM_SELF_INNER = 0;
54acff04ddSBarry Smith #endif
55acff04ddSBarry Smith 
56e5c89e4eSSatish Balay /*
57e5c89e4eSSatish Balay     PetscInitialize_DynamicLibraries - Adds the default dynamic link libraries to the
58e5c89e4eSSatish Balay     search path.
59e5c89e4eSSatish Balay */
6095c0884eSLisandro Dalcin PETSC_INTERN PetscErrorCode PetscInitialize_DynamicLibraries(void)
61e5c89e4eSSatish Balay {
62487e5849SBarry Smith   char           *libname[32];
63e5c89e4eSSatish Balay   PetscErrorCode ierr;
64e5c89e4eSSatish Balay   PetscInt       nmax,i;
65dc21ef1bSBarry Smith #if defined(PETSC_USE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES)
66aa2d57e9SJed Brown   PetscBool      preload;
673fa76a5bSLisandro Dalcin #endif
68*540e20f2SPierre Jolivet #if defined(PETSC_HAVE_ELEMENTAL)
69*540e20f2SPierre Jolivet   PetscBool      PetscInitialized = PetscInitializeCalled;
70*540e20f2SPierre Jolivet #endif
71e5c89e4eSSatish Balay 
7260154eb2SBarry Smith   PetscFunctionBegin;
73e5c89e4eSSatish Balay   nmax = 32;
74c5929fdfSBarry Smith   ierr = PetscOptionsGetStringArray(NULL,NULL,"-dll_prepend",libname,&nmax,NULL);CHKERRQ(ierr);
75e5c89e4eSSatish Balay   for (i=0; i<nmax; i++) {
76d44a1e48SBarry Smith     ierr = PetscDLLibraryPrepend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,libname[i]);CHKERRQ(ierr);
77e5c89e4eSSatish Balay     ierr = PetscFree(libname[i]);CHKERRQ(ierr);
78e5c89e4eSSatish Balay   }
79e5c89e4eSSatish Balay 
80dc21ef1bSBarry Smith #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) || !defined(PETSC_USE_SHARED_LIBRARIES)
813fa76a5bSLisandro Dalcin   /*
823fa76a5bSLisandro Dalcin       This just initializes the most basic PETSc stuff.
833fa76a5bSLisandro Dalcin 
843fa76a5bSLisandro Dalcin     The classes, from PetscDraw to PetscTS, are initialized the first
853fa76a5bSLisandro Dalcin     time an XXCreate() is called.
863fa76a5bSLisandro Dalcin   */
87607a6623SBarry Smith   ierr = PetscSysInitializePackage();CHKERRQ(ierr);
883fa76a5bSLisandro Dalcin #else
89aa2d57e9SJed Brown   preload = PETSC_FALSE;
90c5929fdfSBarry Smith   ierr = PetscOptionsGetBool(NULL,NULL,"-dynamic_library_preload",&preload,NULL);CHKERRQ(ierr);
91aa2d57e9SJed Brown   if (preload) {
92aa2d57e9SJed Brown     PetscBool found;
9360154eb2SBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY)
94487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("",&found);CHKERRQ(ierr);
95e32f2f54SBarry Smith     if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!");
9660154eb2SBarry Smith #else
9760154eb2SBarry Smith     ierr = PetscLoadDynamicLibrary("sys",&found);CHKERRQ(ierr);
9860154eb2SBarry Smith     if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!");
99487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("vec",&found);CHKERRQ(ierr);
100e32f2f54SBarry 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!");
101487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("mat",&found);CHKERRQ(ierr);
102e32f2f54SBarry 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!");
103487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("dm",&found);CHKERRQ(ierr);
104e32f2f54SBarry 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!");
105487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("ksp",&found);CHKERRQ(ierr);
106e32f2f54SBarry 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!");
107487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("snes",&found);CHKERRQ(ierr);
108e32f2f54SBarry 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!");
109487e5849SBarry Smith     ierr = PetscLoadDynamicLibrary("ts",&found);CHKERRQ(ierr);
110e32f2f54SBarry 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!");
111bb84e0fdSBarry Smith #endif
112aa2d57e9SJed Brown   }
1133fa76a5bSLisandro Dalcin #endif
114e5c89e4eSSatish Balay 
115e5c89e4eSSatish Balay   nmax = 32;
116c5929fdfSBarry Smith   ierr = PetscOptionsGetStringArray(NULL,NULL,"-dll_append",libname,&nmax,NULL);CHKERRQ(ierr);
117e5c89e4eSSatish Balay   for (i=0; i<nmax; i++) {
118d44a1e48SBarry Smith     ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,libname[i]);CHKERRQ(ierr);
119e5c89e4eSSatish Balay     ierr = PetscFree(libname[i]);CHKERRQ(ierr);
120e5c89e4eSSatish Balay   }
1213020f62cSBarry Smith 
122acff04ddSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY)
12322b6d1caSBarry Smith   /* These must be done here because it is not safe for individual threads to call these initialize routines */
1243020f62cSBarry Smith   ierr = AOInitializePackage();CHKERRQ(ierr);
1253020f62cSBarry Smith   ierr = PetscSFInitializePackage();CHKERRQ(ierr);
1267da51e29SSatish Balay #if !defined(PETSC_USE_COMPLEX)
1273020f62cSBarry Smith   ierr = CharacteristicInitializePackage();CHKERRQ(ierr);
1287da51e29SSatish Balay #endif
1293020f62cSBarry Smith   ierr = ISInitializePackage();CHKERRQ(ierr);
1303020f62cSBarry Smith   ierr = VecInitializePackage();CHKERRQ(ierr);
1313020f62cSBarry Smith   ierr = MatInitializePackage();CHKERRQ(ierr);
1323020f62cSBarry Smith   ierr = DMInitializePackage();CHKERRQ(ierr);
1333020f62cSBarry Smith   ierr = PCInitializePackage();CHKERRQ(ierr);
1343020f62cSBarry Smith   ierr = KSPInitializePackage();CHKERRQ(ierr);
1353020f62cSBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
1363020f62cSBarry Smith   ierr = TSInitializePackage();CHKERRQ(ierr);
137acff04ddSBarry Smith   ierr = PetscCommDuplicate(PETSC_COMM_SELF,&PETSC_COMM_SELF_INNER,NULL);CHKERRQ(ierr);
138acff04ddSBarry Smith   ierr = PetscCommDuplicate(PETSC_COMM_WORLD,&PETSC_COMM_WORLD_INNER,NULL);CHKERRQ(ierr);
139acff04ddSBarry Smith #endif
140*540e20f2SPierre Jolivet #if defined(PETSC_HAVE_ELEMENTAL)
141*540e20f2SPierre Jolivet   /* in Fortran, PetscInitializeCalled is set to PETSC_TRUE before PetscInitialize_DynamicLibraries() */
142*540e20f2SPierre Jolivet   /* in C, it is not the case, but the value is forced to PETSC_TRUE so that PetscRegisterFinalize() is called */
143*540e20f2SPierre Jolivet   PetscInitializeCalled = PETSC_TRUE;
144*540e20f2SPierre Jolivet   ierr = PetscElementalInitializePackage();CHKERRQ(ierr);
145*540e20f2SPierre Jolivet   PetscInitializeCalled = PetscInitialized;
146*540e20f2SPierre Jolivet #endif
147e5c89e4eSSatish Balay   PetscFunctionReturn(0);
148e5c89e4eSSatish Balay }
149e5c89e4eSSatish Balay 
150ebd79076SLisandro Dalcin /*
151ebd79076SLisandro Dalcin      PetscFinalize_DynamicLibraries - Closes the opened dynamic libraries.
152ebd79076SLisandro Dalcin */
15395c0884eSLisandro Dalcin PETSC_INTERN PetscErrorCode PetscFinalize_DynamicLibraries(void)
154e5c89e4eSSatish Balay {
155ebd79076SLisandro Dalcin   PetscErrorCode ierr;
156ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
157e5c89e4eSSatish Balay 
158ebd79076SLisandro Dalcin   PetscFunctionBegin;
159c5929fdfSBarry Smith   ierr = PetscOptionsGetBool(NULL,NULL,"-dll_view",&flg,NULL);CHKERRQ(ierr);
160d44a1e48SBarry Smith   if (flg) { ierr = PetscDLLibraryPrintPath(PetscDLLibrariesLoaded);CHKERRQ(ierr); }
161d44a1e48SBarry Smith   ierr = PetscDLLibraryClose(PetscDLLibrariesLoaded);CHKERRQ(ierr);
162a297a907SKarl Rupp 
163acff04ddSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY)
164acff04ddSBarry Smith   ierr = PetscCommDestroy(&PETSC_COMM_SELF_INNER);CHKERRQ(ierr);
165acff04ddSBarry Smith   ierr = PetscCommDestroy(&PETSC_COMM_WORLD_INNER);CHKERRQ(ierr);
166acff04ddSBarry Smith #endif
167acff04ddSBarry Smith 
16802c9f0b5SLisandro Dalcin   PetscDLLibrariesLoaded = NULL;
169e5c89e4eSSatish Balay   PetscFunctionReturn(0);
170e5c89e4eSSatish Balay }
171e5c89e4eSSatish Balay 
172e4d1774bSDmitry Karpeev 
173e4d1774bSDmitry Karpeev 
174e5c89e4eSSatish Balay /* ------------------------------------------------------------------------------*/
175140e18c1SBarry Smith struct _n_PetscFunctionList {
176e5c89e4eSSatish Balay   void              (*routine)(void);    /* the routine */
177e5c89e4eSSatish Balay   char              *name;               /* string to identify routine */
178140e18c1SBarry Smith   PetscFunctionList next;                /* next pointer */
179140e18c1SBarry Smith   PetscFunctionList next_list;           /* used to maintain list of all lists for freeing */
180e5c89e4eSSatish Balay };
181e5c89e4eSSatish Balay 
182e5c89e4eSSatish Balay /*
183140e18c1SBarry Smith      Keep a linked list of PetscFunctionLists so that we can destroy all the left-over ones.
184e5c89e4eSSatish Balay */
18502c9f0b5SLisandro Dalcin static PetscFunctionList dlallhead = NULL;
186e5c89e4eSSatish Balay 
187a240a19fSJed Brown /*MC
188140e18c1SBarry Smith    PetscFunctionListAdd - Given a routine and a string id, saves that routine in the
189e5c89e4eSSatish Balay    specified registry.
190e5c89e4eSSatish Balay 
191a240a19fSJed Brown    Synopsis:
192aaa7dc30SBarry Smith    #include <petscsys.h>
193b9fb364aSBarry Smith    PetscErrorCode PetscFunctionListAdd(PetscFunctionList *flist,const char name[],void (*fptr)(void))
194a240a19fSJed Brown 
195d4349b43SBarry Smith    Not Collective
196e5c89e4eSSatish Balay 
197e5c89e4eSSatish Balay    Input Parameters:
198b9fb364aSBarry Smith +  flist - pointer to function list object
199e5c89e4eSSatish Balay .  name - string to identify routine
200a240a19fSJed Brown -  fptr - function pointer
201e5c89e4eSSatish Balay 
202e5c89e4eSSatish Balay    Notes:
203a240a19fSJed Brown    To remove a registered routine, pass in a NULL fptr.
204e5c89e4eSSatish Balay 
205e5c89e4eSSatish Balay    Users who wish to register new classes for use by a particular PETSc
206e5c89e4eSSatish Balay    component (e.g., SNES) should generally call the registration routine
2071c84c290SBarry Smith    for that particular component (e.g., SNESRegister()) instead of
208140e18c1SBarry Smith    calling PetscFunctionListAdd() directly.
209e5c89e4eSSatish Balay 
210e5c89e4eSSatish Balay     Level: developer
211e5c89e4eSSatish Balay 
2121c84c290SBarry Smith .seealso: PetscFunctionListDestroy(), SNESRegister(), KSPRegister(),
213a240a19fSJed Brown           PCRegister(), TSRegister(), PetscFunctionList, PetscObjectComposeFunction()
214a240a19fSJed Brown M*/
215a240a19fSJed Brown PETSC_EXTERN PetscErrorCode PetscFunctionListAdd_Private(PetscFunctionList *fl,const char name[],void (*fnc)(void))
216e5c89e4eSSatish Balay {
217140e18c1SBarry Smith   PetscFunctionList entry,ne;
218e5c89e4eSSatish Balay   PetscErrorCode    ierr;
219e5c89e4eSSatish Balay 
220e5c89e4eSSatish Balay   PetscFunctionBegin;
221e5c89e4eSSatish Balay   if (!*fl) {
222b00a9115SJed Brown     ierr           = PetscNew(&entry);CHKERRQ(ierr);
223e5c89e4eSSatish Balay     ierr           = PetscStrallocpy(name,&entry->name);CHKERRQ(ierr);
224e5c89e4eSSatish Balay     entry->routine = fnc;
22502c9f0b5SLisandro Dalcin     entry->next    = NULL;
226e5c89e4eSSatish Balay     *fl            = entry;
227e5c89e4eSSatish Balay 
228a2553e36SBarry Smith #if defined(PETSC_USE_DEBUG)
229e5c89e4eSSatish Balay     /* add this new list to list of all lists */
230e5c89e4eSSatish Balay     if (!dlallhead) {
231e5c89e4eSSatish Balay       dlallhead        = *fl;
23202c9f0b5SLisandro Dalcin       (*fl)->next_list = NULL;
233e5c89e4eSSatish Balay     } else {
234e5c89e4eSSatish Balay       ne               = dlallhead;
235e5c89e4eSSatish Balay       dlallhead        = *fl;
236e5c89e4eSSatish Balay       (*fl)->next_list = ne;
237e5c89e4eSSatish Balay     }
238a8a6328fSBarry Smith #endif
239a8a6328fSBarry Smith 
240e5c89e4eSSatish Balay   } else {
241e5c89e4eSSatish Balay     /* search list to see if it is already there */
242e5c89e4eSSatish Balay     ne = *fl;
243e5c89e4eSSatish Balay     while (ne) {
244ace3abfcSBarry Smith       PetscBool founddup;
245e5c89e4eSSatish Balay 
246e5c89e4eSSatish Balay       ierr = PetscStrcmp(ne->name,name,&founddup);CHKERRQ(ierr);
247e5c89e4eSSatish Balay       if (founddup) { /* found duplicate */
248e5c89e4eSSatish Balay         ne->routine = fnc;
249e5c89e4eSSatish Balay         PetscFunctionReturn(0);
250e5c89e4eSSatish Balay       }
251a297a907SKarl Rupp       if (ne->next) ne = ne->next;
252a297a907SKarl Rupp       else break;
253e5c89e4eSSatish Balay     }
254e5c89e4eSSatish Balay     /* create new entry and add to end of list */
255b00a9115SJed Brown     ierr           = PetscNew(&entry);CHKERRQ(ierr);
256e5c89e4eSSatish Balay     ierr           = PetscStrallocpy(name,&entry->name);CHKERRQ(ierr);
257e5c89e4eSSatish Balay     entry->routine = fnc;
25802c9f0b5SLisandro Dalcin     entry->next    = NULL;
259e5c89e4eSSatish Balay     ne->next       = entry;
260e5c89e4eSSatish Balay   }
261e5c89e4eSSatish Balay   PetscFunctionReturn(0);
262e5c89e4eSSatish Balay }
263e5c89e4eSSatish Balay 
264e5c89e4eSSatish Balay /*@
265140e18c1SBarry Smith     PetscFunctionListDestroy - Destroys a list of registered routines.
266e5c89e4eSSatish Balay 
267e5c89e4eSSatish Balay     Input Parameter:
268e5c89e4eSSatish Balay .   fl  - pointer to list
269e5c89e4eSSatish Balay 
270e5c89e4eSSatish Balay     Level: developer
271e5c89e4eSSatish Balay 
272a240a19fSJed Brown .seealso: PetscFunctionListAdd(), PetscFunctionList
273e5c89e4eSSatish Balay @*/
274140e18c1SBarry Smith PetscErrorCode  PetscFunctionListDestroy(PetscFunctionList *fl)
275e5c89e4eSSatish Balay {
276140e18c1SBarry Smith   PetscFunctionList next,entry,tmp = dlallhead;
277e5c89e4eSSatish Balay   PetscErrorCode    ierr;
278e5c89e4eSSatish Balay 
279e5c89e4eSSatish Balay   PetscFunctionBegin;
2801441b1d3SBarry Smith   if (!*fl) PetscFunctionReturn(0);
281e5c89e4eSSatish Balay 
282e5c89e4eSSatish Balay   /*
283e5c89e4eSSatish Balay        Remove this entry from the master DL list (if it is in it)
284e5c89e4eSSatish Balay   */
2851441b1d3SBarry Smith   if (dlallhead == *fl) {
286a297a907SKarl Rupp     if (dlallhead->next_list) dlallhead = dlallhead->next_list;
28737e93019SBarry Smith     else dlallhead = NULL;
28837e93019SBarry Smith   } else if (tmp) {
2891441b1d3SBarry Smith     while (tmp->next_list != *fl) {
290e5c89e4eSSatish Balay       tmp = tmp->next_list;
291e5c89e4eSSatish Balay       if (!tmp->next_list) break;
292e5c89e4eSSatish Balay     }
293e5c89e4eSSatish Balay     if (tmp->next_list) tmp->next_list = tmp->next_list->next_list;
294e5c89e4eSSatish Balay   }
295e5c89e4eSSatish Balay 
296e5c89e4eSSatish Balay   /* free this list */
2971441b1d3SBarry Smith   entry = *fl;
298e5c89e4eSSatish Balay   while (entry) {
299e5c89e4eSSatish Balay     next  = entry->next;
300e5c89e4eSSatish Balay     ierr  = PetscFree(entry->name);CHKERRQ(ierr);
301e5c89e4eSSatish Balay     ierr  = PetscFree(entry);CHKERRQ(ierr);
302e5c89e4eSSatish Balay     entry = next;
303e5c89e4eSSatish Balay   }
30402c9f0b5SLisandro Dalcin   *fl = NULL;
305e5c89e4eSSatish Balay   PetscFunctionReturn(0);
306e5c89e4eSSatish Balay }
307e5c89e4eSSatish Balay 
308e5c89e4eSSatish Balay /*
30937e93019SBarry Smith    Print any PetscFunctionLists that have not be destroyed
310e5c89e4eSSatish Balay */
31137e93019SBarry Smith PetscErrorCode  PetscFunctionListPrintAll(void)
312e5c89e4eSSatish Balay {
31337e93019SBarry Smith   PetscFunctionList tmp = dlallhead;
314e5c89e4eSSatish Balay   PetscErrorCode    ierr;
315e5c89e4eSSatish Balay 
316e5c89e4eSSatish Balay   PetscFunctionBegin;
31737e93019SBarry Smith   if (tmp) {
31837e93019SBarry Smith     ierr = PetscPrintf(PETSC_COMM_WORLD,"The following PetscFunctionLists were not destroyed\n");CHKERRQ(ierr);
319e5c89e4eSSatish Balay   }
32037e93019SBarry Smith   while (tmp) {
32137e93019SBarry Smith     ierr = PetscPrintf(PETSC_COMM_WORLD,"%s \n",tmp->name);CHKERRQ(ierr);
32237e93019SBarry Smith     tmp = tmp->next_list;
32337e93019SBarry Smith   }
324e5c89e4eSSatish Balay   PetscFunctionReturn(0);
325e5c89e4eSSatish Balay }
326e5c89e4eSSatish Balay 
3271c9cd337SJed Brown /*MC
3281c9cd337SJed Brown     PetscFunctionListFind - Find function registered under given name
3291c9cd337SJed Brown 
3301c9cd337SJed Brown     Synopsis:
331aaa7dc30SBarry Smith     #include <petscsys.h>
3321c9cd337SJed Brown     PetscErrorCode PetscFunctionListFind(PetscFunctionList flist,const char name[],void (**fptr)(void))
333e5c89e4eSSatish Balay 
334e5c89e4eSSatish Balay     Input Parameters:
3351c9cd337SJed Brown +   flist   - pointer to list
3361c9cd337SJed Brown -   name - name registered for the function
337e5c89e4eSSatish Balay 
338e5c89e4eSSatish Balay     Output Parameters:
3391c9cd337SJed Brown .   fptr - the function pointer if name was found, else NULL
340e5c89e4eSSatish Balay 
341e5c89e4eSSatish Balay     Level: developer
342e5c89e4eSSatish Balay 
3431c9cd337SJed Brown .seealso: PetscFunctionListAdd(), PetscFunctionList, PetscObjectQueryFunction()
3441c9cd337SJed Brown M*/
3451c9cd337SJed Brown PETSC_EXTERN PetscErrorCode PetscFunctionListFind_Private(PetscFunctionList fl,const char name[],void (**r)(void))
346e5c89e4eSSatish Balay {
347140e18c1SBarry Smith   PetscFunctionList entry = fl;
348e5c89e4eSSatish Balay   PetscErrorCode    ierr;
349bdf89e91SBarry Smith   PetscBool         flg;
350e5c89e4eSSatish Balay 
351e5c89e4eSSatish Balay   PetscFunctionBegin;
352e32f2f54SBarry Smith   if (!name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to find routine with null name");
353e5c89e4eSSatish Balay 
35402c9f0b5SLisandro Dalcin   *r = NULL;
355e5c89e4eSSatish Balay   while (entry) {
356bdf89e91SBarry Smith     ierr = PetscStrcmp(name,entry->name,&flg);CHKERRQ(ierr);
357bdf89e91SBarry Smith     if (flg) {
358e5c89e4eSSatish Balay       *r   = entry->routine;
359e5c89e4eSSatish Balay       PetscFunctionReturn(0);
360e5c89e4eSSatish Balay     }
361e5c89e4eSSatish Balay     entry = entry->next;
362e5c89e4eSSatish Balay   }
363e5c89e4eSSatish Balay   PetscFunctionReturn(0);
364e5c89e4eSSatish Balay }
365e5c89e4eSSatish Balay 
366e5c89e4eSSatish Balay /*@
367140e18c1SBarry Smith    PetscFunctionListView - prints out contents of an PetscFunctionList
368e5c89e4eSSatish Balay 
369e5c89e4eSSatish Balay    Collective over MPI_Comm
370e5c89e4eSSatish Balay 
371e5c89e4eSSatish Balay    Input Parameters:
372e5c89e4eSSatish Balay +  list - the list of functions
373e5c89e4eSSatish Balay -  viewer - currently ignored
374e5c89e4eSSatish Balay 
375e5c89e4eSSatish Balay    Level: developer
376e5c89e4eSSatish Balay 
377a240a19fSJed Brown .seealso: PetscFunctionListAdd(), PetscFunctionListPrintTypes(), PetscFunctionList
378e5c89e4eSSatish Balay @*/
379140e18c1SBarry Smith PetscErrorCode  PetscFunctionListView(PetscFunctionList list,PetscViewer viewer)
380e5c89e4eSSatish Balay {
381e5c89e4eSSatish Balay   PetscErrorCode ierr;
382ace3abfcSBarry Smith   PetscBool      iascii;
383e5c89e4eSSatish Balay 
384e5c89e4eSSatish Balay   PetscFunctionBegin;
385e5c89e4eSSatish Balay   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
386e5c89e4eSSatish Balay   PetscValidPointer(list,1);
3870700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
388e5c89e4eSSatish Balay 
389251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
390e32f2f54SBarry Smith   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only ASCII viewer supported");
391e5c89e4eSSatish Balay 
392e5c89e4eSSatish Balay   while (list) {
393bdf89e91SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %s\n",list->name);CHKERRQ(ierr);
394e5c89e4eSSatish Balay     list = list->next;
395e5c89e4eSSatish Balay   }
396e5c89e4eSSatish Balay   ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
397e5c89e4eSSatish Balay   PetscFunctionReturn(0);
398e5c89e4eSSatish Balay }
399e5c89e4eSSatish Balay 
400065533a5SJed Brown /*@C
401140e18c1SBarry Smith    PetscFunctionListGet - Gets an array the contains the entries in PetscFunctionList, this is used
402e5c89e4eSSatish Balay          by help etc.
403e5c89e4eSSatish Balay 
404d4349b43SBarry Smith    Not Collective
405e5c89e4eSSatish Balay 
406e5c89e4eSSatish Balay    Input Parameter:
407e5c89e4eSSatish Balay .  list   - list of types
408e5c89e4eSSatish Balay 
409e5c89e4eSSatish Balay    Output Parameter:
410e5c89e4eSSatish Balay +  array - array of names
411e5c89e4eSSatish Balay -  n - length of array
412e5c89e4eSSatish Balay 
413e5c89e4eSSatish Balay    Notes:
414e5c89e4eSSatish Balay        This allocates the array so that must be freed. BUT the individual entries are
415e5c89e4eSSatish Balay     not copied so should not be freed.
416e5c89e4eSSatish Balay 
417e5c89e4eSSatish Balay    Level: developer
418e5c89e4eSSatish Balay 
419a240a19fSJed Brown .seealso: PetscFunctionListAdd(), PetscFunctionList
420e5c89e4eSSatish Balay @*/
421ca1b3570SJed Brown PetscErrorCode  PetscFunctionListGet(PetscFunctionList list,const char ***array,int *n)
422e5c89e4eSSatish Balay {
423e5c89e4eSSatish Balay   PetscErrorCode    ierr;
424e5c89e4eSSatish Balay   PetscInt          count = 0;
425140e18c1SBarry Smith   PetscFunctionList klist = list;
426e5c89e4eSSatish Balay 
427e5c89e4eSSatish Balay   PetscFunctionBegin;
428e5c89e4eSSatish Balay   while (list) {
429e5c89e4eSSatish Balay     list = list->next;
430e5c89e4eSSatish Balay     count++;
431e5c89e4eSSatish Balay   }
432ca1b3570SJed Brown   ierr  = PetscMalloc1(count+1,(char***)array);CHKERRQ(ierr);
433e5c89e4eSSatish Balay   count = 0;
434e5c89e4eSSatish Balay   while (klist) {
435e5c89e4eSSatish Balay     (*array)[count] = klist->name;
436e5c89e4eSSatish Balay     klist           = klist->next;
437e5c89e4eSSatish Balay     count++;
438e5c89e4eSSatish Balay   }
43902c9f0b5SLisandro Dalcin   (*array)[count] = NULL;
440e5c89e4eSSatish Balay   *n              = count+1;
441e5c89e4eSSatish Balay   PetscFunctionReturn(0);
442e5c89e4eSSatish Balay }
443e5c89e4eSSatish Balay 
444e5c89e4eSSatish Balay 
445e5c89e4eSSatish Balay /*@C
446140e18c1SBarry Smith    PetscFunctionListPrintTypes - Prints the methods available.
447e5c89e4eSSatish Balay 
448e5c89e4eSSatish Balay    Collective over MPI_Comm
449e5c89e4eSSatish Balay 
450e5c89e4eSSatish Balay    Input Parameters:
451e5c89e4eSSatish Balay +  comm   - the communicator (usually MPI_COMM_WORLD)
452e5c89e4eSSatish Balay .  fd     - file to print to, usually stdout
453e5c89e4eSSatish Balay .  prefix - prefix to prepend to name (optional)
454e5c89e4eSSatish Balay .  name   - option string (for example, "-ksp_type")
455e5c89e4eSSatish Balay .  text - short description of the object (for example, "Krylov solvers")
456e5c89e4eSSatish Balay .  man - name of manual page that discusses the object (for example, "KSPCreate")
4573cc1e11dSBarry Smith .  list   - list of types
45844ef3d73SBarry Smith .  def - default (current) value
45944ef3d73SBarry Smith -  newv - new value
460e5c89e4eSSatish Balay 
461e5c89e4eSSatish Balay    Level: developer
462e5c89e4eSSatish Balay 
463a240a19fSJed Brown .seealso: PetscFunctionListAdd(), PetscFunctionList
464e5c89e4eSSatish Balay @*/
46544ef3d73SBarry 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[],const char newv[])
466e5c89e4eSSatish Balay {
467e5c89e4eSSatish Balay   PetscErrorCode ierr;
468e5c89e4eSSatish Balay   char           p[64];
469e5c89e4eSSatish Balay 
470e5c89e4eSSatish Balay   PetscFunctionBegin;
471da9f1d6bSBarry Smith   if (!fd) fd = PETSC_STDOUT;
472e5c89e4eSSatish Balay 
473a126751eSBarry Smith   ierr = PetscStrncpy(p,"-",sizeof(p));CHKERRQ(ierr);
474a126751eSBarry Smith   if (prefix) {ierr = PetscStrlcat(p,prefix,sizeof(p));CHKERRQ(ierr);}
4750e4c290aSBarry Smith   ierr = PetscFPrintf(comm,fd,"  %s%s <now %s : formerly %s>: %s (one of)",p,name+1,newv,def,text);CHKERRQ(ierr);
476e5c89e4eSSatish Balay 
477e5c89e4eSSatish Balay   while (list) {
478e5c89e4eSSatish Balay     ierr = PetscFPrintf(comm,fd," %s",list->name);CHKERRQ(ierr);
479e5c89e4eSSatish Balay     list = list->next;
480e5c89e4eSSatish Balay   }
481e5c89e4eSSatish Balay   ierr = PetscFPrintf(comm,fd," (%s)\n",man);CHKERRQ(ierr);
482e5c89e4eSSatish Balay   PetscFunctionReturn(0);
483e5c89e4eSSatish Balay }
484e5c89e4eSSatish Balay 
485e5c89e4eSSatish Balay /*@
486140e18c1SBarry Smith     PetscFunctionListDuplicate - Creates a new list from a given object list.
487e5c89e4eSSatish Balay 
488e5c89e4eSSatish Balay     Input Parameters:
489e5c89e4eSSatish Balay .   fl   - pointer to list
490e5c89e4eSSatish Balay 
491e5c89e4eSSatish Balay     Output Parameters:
492e5c89e4eSSatish Balay .   nl - the new list (should point to 0 to start, otherwise appends)
493e5c89e4eSSatish Balay 
494e5c89e4eSSatish Balay     Level: developer
495e5c89e4eSSatish Balay 
496140e18c1SBarry Smith .seealso: PetscFunctionList, PetscFunctionListAdd(), PetscFlistDestroy()
497e5c89e4eSSatish Balay 
498e5c89e4eSSatish Balay @*/
499140e18c1SBarry Smith PetscErrorCode  PetscFunctionListDuplicate(PetscFunctionList fl,PetscFunctionList *nl)
500e5c89e4eSSatish Balay {
501e5c89e4eSSatish Balay   PetscErrorCode ierr;
502e5c89e4eSSatish Balay 
503e5c89e4eSSatish Balay   PetscFunctionBegin;
504e5c89e4eSSatish Balay   while (fl) {
505bdf89e91SBarry Smith     ierr = PetscFunctionListAdd(nl,fl->name,fl->routine);CHKERRQ(ierr);
506e5c89e4eSSatish Balay     fl   = fl->next;
507e5c89e4eSSatish Balay   }
508e5c89e4eSSatish Balay   PetscFunctionReturn(0);
509e5c89e4eSSatish Balay }
510e5c89e4eSSatish Balay 
511