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 169371c9d4SSatish Balay static PetscErrorCode PetscLoadDynamicLibrary(const char *name, PetscBool *found) { 17487e5849SBarry Smith char libs[PETSC_MAX_PATH_LEN], dlib[PETSC_MAX_PATH_LEN]; 18487e5849SBarry Smith 19487e5849SBarry Smith PetscFunctionBegin; 209566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(libs, "${PETSC_LIB_DIR}/libpetsc", sizeof(libs))); 219566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(libs, name, sizeof(libs))); 229566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryRetrieve(PETSC_COMM_WORLD, libs, dlib, 1024, found)); 23487e5849SBarry Smith if (*found) { 249566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, dlib)); 25487e5849SBarry Smith } else { 269566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(libs, "${PETSC_DIR}/${PETSC_ARCH}/lib/libpetsc", sizeof(libs))); 279566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(libs, name, sizeof(libs))); 289566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryRetrieve(PETSC_COMM_WORLD, libs, dlib, 1024, found)); 29*48a46eb9SPierre Jolivet if (*found) PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, dlib)); 30487e5849SBarry Smith } 31487e5849SBarry Smith PetscFunctionReturn(0); 32487e5849SBarry Smith } 333fa76a5bSLisandro Dalcin #endif 343fa76a5bSLisandro Dalcin 3560da17ecSBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY) && !(defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES)) 3695c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode AOInitializePackage(void); 3795c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscSFInitializePackage(void); 387da51e29SSatish Balay #if !defined(PETSC_USE_COMPLEX) 3995c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode CharacteristicInitializePackage(void); 407da51e29SSatish Balay #endif 4195c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode ISInitializePackage(void); 4295c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode VecInitializePackage(void); 4395c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode MatInitializePackage(void); 4495c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode DMInitializePackage(void); 4595c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PCInitializePackage(void); 4695c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode KSPInitializePackage(void); 4795c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode SNESInitializePackage(void); 4895c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode TSInitializePackage(void); 4960da17ecSBarry Smith PETSC_EXTERN PetscErrorCode TaoInitializePackage(void); 5060da17ecSBarry Smith #endif 5160da17ecSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY) 5222b6d1caSBarry Smith static MPI_Comm PETSC_COMM_WORLD_INNER = 0, PETSC_COMM_SELF_INNER = 0; 53acff04ddSBarry Smith #endif 54acff04ddSBarry Smith 55e5c89e4eSSatish Balay /* 56e5c89e4eSSatish Balay PetscInitialize_DynamicLibraries - Adds the default dynamic link libraries to the 57e5c89e4eSSatish Balay search path. 58e5c89e4eSSatish Balay */ 599371c9d4SSatish Balay PETSC_INTERN PetscErrorCode PetscInitialize_DynamicLibraries(void) { 60487e5849SBarry Smith char *libname[32]; 61e5c89e4eSSatish Balay PetscInt nmax, i; 6260da17ecSBarry Smith PetscBool preload = PETSC_FALSE; 63540e20f2SPierre Jolivet #if defined(PETSC_HAVE_ELEMENTAL) 64540e20f2SPierre Jolivet PetscBool PetscInitialized = PetscInitializeCalled; 65540e20f2SPierre Jolivet #endif 66e5c89e4eSSatish Balay 6760154eb2SBarry Smith PetscFunctionBegin; 6860da17ecSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY) 6960da17ecSBarry Smith /* These must be all initialized here because it is not safe for individual threads to call these initialize routines */ 7060da17ecSBarry Smith preload = PETSC_TRUE; 7160da17ecSBarry Smith #endif 7260da17ecSBarry Smith 73e5c89e4eSSatish Balay nmax = 32; 749566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(NULL, NULL, "-dll_prepend", libname, &nmax, NULL)); 75e5c89e4eSSatish Balay for (i = 0; i < nmax; i++) { 769566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryPrepend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, libname[i])); 779566063dSJacob Faibussowitsch PetscCall(PetscFree(libname[i])); 78e5c89e4eSSatish Balay } 79e5c89e4eSSatish Balay 809566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-library_preload", &preload, NULL)); 8160da17ecSBarry Smith if (!preload) { 829566063dSJacob Faibussowitsch PetscCall(PetscSysInitializePackage()); 8360da17ecSBarry Smith } else { 8460da17ecSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) 85aa2d57e9SJed Brown PetscBool found; 8660154eb2SBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY) 879566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("", &found)); 8828b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!"); 8960154eb2SBarry Smith #else 909566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("sys", &found)); 9128b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!"); 929566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("vec", &found)); 9328b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc Vec dynamic library \n You cannot move the dynamic libraries!"); 949566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("mat", &found)); 9528b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc Mat dynamic library \n You cannot move the dynamic libraries!"); 969566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("dm", &found)); 9728b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc DM dynamic library \n You cannot move the dynamic libraries!"); 989566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("ksp", &found)); 9928b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc KSP dynamic library \n You cannot move the dynamic libraries!"); 1009566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("snes", &found)); 10128b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc SNES dynamic library \n You cannot move the dynamic libraries!"); 1029566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("ts", &found)); 10328b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc TS dynamic library \n You cannot move the dynamic libraries!"); 1049566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("tao", &found)); 10528b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate Tao dynamic library \n You cannot move the dynamic libraries!"); 106bb84e0fdSBarry Smith #endif 10760da17ecSBarry Smith #else /* defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) */ 10860da17ecSBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY) 1099566063dSJacob Faibussowitsch PetscCall(AOInitializePackage()); 1109566063dSJacob Faibussowitsch PetscCall(PetscSFInitializePackage()); 1117da51e29SSatish Balay #if !defined(PETSC_USE_COMPLEX) 1129566063dSJacob Faibussowitsch PetscCall(CharacteristicInitializePackage()); 1137da51e29SSatish Balay #endif 1149566063dSJacob Faibussowitsch PetscCall(ISInitializePackage()); 1159566063dSJacob Faibussowitsch PetscCall(VecInitializePackage()); 1169566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 1179566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 1189566063dSJacob Faibussowitsch PetscCall(PCInitializePackage()); 1199566063dSJacob Faibussowitsch PetscCall(KSPInitializePackage()); 1209566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 1219566063dSJacob Faibussowitsch PetscCall(TSInitializePackage()); 1229566063dSJacob Faibussowitsch PetscCall(TaoInitializePackage()); 12360da17ecSBarry Smith #else 12460da17ecSBarry Smith SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "Cannot use -library_preload with multiple static PETSc libraries"); 12560da17ecSBarry Smith #endif 12660da17ecSBarry Smith #endif /* defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) */ 12760da17ecSBarry Smith } 12860da17ecSBarry Smith 12960da17ecSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) && defined(PETSC_HAVE_BAMG) 13060da17ecSBarry Smith { 13160da17ecSBarry Smith PetscBool found; 1329566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("bamg", &found)); 13328b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc BAMG dynamic library \n You cannot move the dynamic libraries!"); 13460da17ecSBarry Smith } 13560da17ecSBarry Smith #endif 13660da17ecSBarry Smith 13760da17ecSBarry Smith nmax = 32; 1389566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(NULL, NULL, "-dll_append", libname, &nmax, NULL)); 13960da17ecSBarry Smith for (i = 0; i < nmax; i++) { 1409566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, libname[i])); 1419566063dSJacob Faibussowitsch PetscCall(PetscFree(libname[i])); 14260da17ecSBarry Smith } 14360da17ecSBarry Smith 14460da17ecSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY) 1459566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(PETSC_COMM_SELF, &PETSC_COMM_SELF_INNER, NULL)); 1469566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(PETSC_COMM_WORLD, &PETSC_COMM_WORLD_INNER, NULL)); 147acff04ddSBarry Smith #endif 148540e20f2SPierre Jolivet #if defined(PETSC_HAVE_ELEMENTAL) 149540e20f2SPierre Jolivet /* in Fortran, PetscInitializeCalled is set to PETSC_TRUE before PetscInitialize_DynamicLibraries() */ 150540e20f2SPierre Jolivet /* in C, it is not the case, but the value is forced to PETSC_TRUE so that PetscRegisterFinalize() is called */ 151540e20f2SPierre Jolivet PetscInitializeCalled = PETSC_TRUE; 1529566063dSJacob Faibussowitsch PetscCall(PetscElementalInitializePackage()); 153540e20f2SPierre Jolivet PetscInitializeCalled = PetscInitialized; 154540e20f2SPierre Jolivet #endif 155e5c89e4eSSatish Balay PetscFunctionReturn(0); 156e5c89e4eSSatish Balay } 157e5c89e4eSSatish Balay 158ebd79076SLisandro Dalcin /* 159ebd79076SLisandro Dalcin PetscFinalize_DynamicLibraries - Closes the opened dynamic libraries. 160ebd79076SLisandro Dalcin */ 1619371c9d4SSatish Balay PETSC_INTERN PetscErrorCode PetscFinalize_DynamicLibraries(void) { 162ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 163e5c89e4eSSatish Balay 164ebd79076SLisandro Dalcin PetscFunctionBegin; 1659566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-dll_view", &flg, NULL)); 1669566063dSJacob Faibussowitsch if (flg) PetscCall(PetscDLLibraryPrintPath(PetscDLLibrariesLoaded)); 1679566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryClose(PetscDLLibrariesLoaded)); 168a297a907SKarl Rupp 169acff04ddSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY) 1709566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&PETSC_COMM_SELF_INNER)); 1719566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&PETSC_COMM_WORLD_INNER)); 172acff04ddSBarry Smith #endif 173acff04ddSBarry Smith 17402c9f0b5SLisandro Dalcin PetscDLLibrariesLoaded = NULL; 175e5c89e4eSSatish Balay PetscFunctionReturn(0); 176e5c89e4eSSatish Balay } 177e5c89e4eSSatish Balay 178e5c89e4eSSatish Balay /* ------------------------------------------------------------------------------*/ 179140e18c1SBarry Smith struct _n_PetscFunctionList { 180e5c89e4eSSatish Balay void (*routine)(void); /* the routine */ 181e5c89e4eSSatish Balay char *name; /* string to identify routine */ 182140e18c1SBarry Smith PetscFunctionList next; /* next pointer */ 183140e18c1SBarry Smith PetscFunctionList next_list; /* used to maintain list of all lists for freeing */ 184e5c89e4eSSatish Balay }; 185e5c89e4eSSatish Balay 186e5c89e4eSSatish Balay /* 187140e18c1SBarry Smith Keep a linked list of PetscFunctionLists so that we can destroy all the left-over ones. 188e5c89e4eSSatish Balay */ 18902c9f0b5SLisandro Dalcin static PetscFunctionList dlallhead = NULL; 190e5c89e4eSSatish Balay 191a240a19fSJed Brown /*MC 192140e18c1SBarry Smith PetscFunctionListAdd - Given a routine and a string id, saves that routine in the 193e5c89e4eSSatish Balay specified registry. 194e5c89e4eSSatish Balay 195a240a19fSJed Brown Synopsis: 196aaa7dc30SBarry Smith #include <petscsys.h> 197b9fb364aSBarry Smith PetscErrorCode PetscFunctionListAdd(PetscFunctionList *flist,const char name[],void (*fptr)(void)) 198a240a19fSJed Brown 199d4349b43SBarry Smith Not Collective 200e5c89e4eSSatish Balay 201e5c89e4eSSatish Balay Input Parameters: 202b9fb364aSBarry Smith + flist - pointer to function list object 203e5c89e4eSSatish Balay . name - string to identify routine 204a240a19fSJed Brown - fptr - function pointer 205e5c89e4eSSatish Balay 206e5c89e4eSSatish Balay Notes: 207a240a19fSJed Brown To remove a registered routine, pass in a NULL fptr. 208e5c89e4eSSatish Balay 209e5c89e4eSSatish Balay Users who wish to register new classes for use by a particular PETSc 210e5c89e4eSSatish Balay component (e.g., SNES) should generally call the registration routine 2111c84c290SBarry Smith for that particular component (e.g., SNESRegister()) instead of 212140e18c1SBarry Smith calling PetscFunctionListAdd() directly. 213e5c89e4eSSatish Balay 214e5c89e4eSSatish Balay Level: developer 215e5c89e4eSSatish Balay 216db781477SPatrick Sanan .seealso: `PetscFunctionListDestroy()`, `SNESRegister()`, `KSPRegister()`, 217db781477SPatrick Sanan `PCRegister()`, `TSRegister()`, `PetscFunctionList`, `PetscObjectComposeFunction()` 218a240a19fSJed Brown M*/ 2199371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscFunctionListAdd_Private(PetscFunctionList *fl, const char name[], void (*fnc)(void)) { 220140e18c1SBarry Smith PetscFunctionList entry, ne; 221e5c89e4eSSatish Balay 222e5c89e4eSSatish Balay PetscFunctionBegin; 223e5c89e4eSSatish Balay if (!*fl) { 2249566063dSJacob Faibussowitsch PetscCall(PetscNew(&entry)); 2259566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &entry->name)); 226e5c89e4eSSatish Balay entry->routine = fnc; 22702c9f0b5SLisandro Dalcin entry->next = NULL; 228e5c89e4eSSatish Balay *fl = entry; 229e5c89e4eSSatish Balay 23076bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 231e5c89e4eSSatish Balay /* add this new list to list of all lists */ 232e5c89e4eSSatish Balay if (!dlallhead) { 233e5c89e4eSSatish Balay dlallhead = *fl; 23402c9f0b5SLisandro Dalcin (*fl)->next_list = NULL; 235e5c89e4eSSatish Balay } else { 236e5c89e4eSSatish Balay ne = dlallhead; 237e5c89e4eSSatish Balay dlallhead = *fl; 238e5c89e4eSSatish Balay (*fl)->next_list = ne; 239e5c89e4eSSatish Balay } 24076bd3646SJed Brown } 241a8a6328fSBarry Smith 242e5c89e4eSSatish Balay } else { 243e5c89e4eSSatish Balay /* search list to see if it is already there */ 244e5c89e4eSSatish Balay ne = *fl; 245e5c89e4eSSatish Balay while (ne) { 246ace3abfcSBarry Smith PetscBool founddup; 247e5c89e4eSSatish Balay 2489566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(ne->name, name, &founddup)); 249e5c89e4eSSatish Balay if (founddup) { /* found duplicate */ 250e5c89e4eSSatish Balay ne->routine = fnc; 251e5c89e4eSSatish Balay PetscFunctionReturn(0); 252e5c89e4eSSatish Balay } 253a297a907SKarl Rupp if (ne->next) ne = ne->next; 254a297a907SKarl Rupp else break; 255e5c89e4eSSatish Balay } 256e5c89e4eSSatish Balay /* create new entry and add to end of list */ 2579566063dSJacob Faibussowitsch PetscCall(PetscNew(&entry)); 2589566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &entry->name)); 259e5c89e4eSSatish Balay entry->routine = fnc; 26002c9f0b5SLisandro Dalcin entry->next = NULL; 261e5c89e4eSSatish Balay ne->next = entry; 262e5c89e4eSSatish Balay } 263e5c89e4eSSatish Balay PetscFunctionReturn(0); 264e5c89e4eSSatish Balay } 265e5c89e4eSSatish Balay 266e5c89e4eSSatish Balay /*@ 267140e18c1SBarry Smith PetscFunctionListDestroy - Destroys a list of registered routines. 268e5c89e4eSSatish Balay 269e5c89e4eSSatish Balay Input Parameter: 270e5c89e4eSSatish Balay . fl - pointer to list 271e5c89e4eSSatish Balay 272e5c89e4eSSatish Balay Level: developer 273e5c89e4eSSatish Balay 274db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionList` 275e5c89e4eSSatish Balay @*/ 2769371c9d4SSatish Balay PetscErrorCode PetscFunctionListDestroy(PetscFunctionList *fl) { 277140e18c1SBarry Smith PetscFunctionList next, entry, tmp = dlallhead; 278e5c89e4eSSatish Balay 279e5c89e4eSSatish Balay PetscFunctionBegin; 2801441b1d3SBarry Smith if (!*fl) PetscFunctionReturn(0); 281e5c89e4eSSatish Balay 282e5c89e4eSSatish Balay /* 2839dddd249SSatish Balay Remove this entry from the main 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; 3009566063dSJacob Faibussowitsch PetscCall(PetscFree(entry->name)); 3019566063dSJacob Faibussowitsch PetscCall(PetscFree(entry)); 302e5c89e4eSSatish Balay entry = next; 303e5c89e4eSSatish Balay } 30402c9f0b5SLisandro Dalcin *fl = NULL; 305e5c89e4eSSatish Balay PetscFunctionReturn(0); 306e5c89e4eSSatish Balay } 307e5c89e4eSSatish Balay 308e5c89e4eSSatish Balay /* 3092e956fe4SStefano Zampini Print registered PetscFunctionLists 310e5c89e4eSSatish Balay */ 3119371c9d4SSatish Balay PetscErrorCode PetscFunctionListPrintAll(void) { 31237e93019SBarry Smith PetscFunctionList tmp = dlallhead; 313e5c89e4eSSatish Balay 314e5c89e4eSSatish Balay PetscFunctionBegin; 3152e956fe4SStefano Zampini if (tmp) PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Registered PetscFunctionLists\n", PetscGlobalRank)); 31637e93019SBarry Smith while (tmp) { 3172e956fe4SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] %s\n", PetscGlobalRank, tmp->name)); 31837e93019SBarry Smith tmp = tmp->next_list; 31937e93019SBarry Smith } 320e5c89e4eSSatish Balay PetscFunctionReturn(0); 321e5c89e4eSSatish Balay } 322e5c89e4eSSatish Balay 3231c9cd337SJed Brown /*MC 3242e956fe4SStefano Zampini PetscFunctionListNonEmpty - Print composed names for non null function pointers 3252e956fe4SStefano Zampini 3262e956fe4SStefano Zampini Input Parameter: 3272e956fe4SStefano Zampini . flist - pointer to list 3282e956fe4SStefano Zampini 3292e956fe4SStefano Zampini Level: developer 3302e956fe4SStefano Zampini 3312e956fe4SStefano Zampini .seealso: `PetscFunctionListAdd()`, `PetscFunctionList`, `PetscObjectQueryFunction()` 3322e956fe4SStefano Zampini M*/ 3339371c9d4SSatish Balay PetscErrorCode PetscFunctionListPrintNonEmpty(PetscFunctionList fl) { 3342e956fe4SStefano Zampini PetscFunctionBegin; 3352e956fe4SStefano Zampini while (fl) { 3362e956fe4SStefano Zampini PetscFunctionList next = fl->next; 3372e956fe4SStefano Zampini if (fl->routine) PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] function name: %s\n", PetscGlobalRank, fl->name)); 3382e956fe4SStefano Zampini fl = next; 3392e956fe4SStefano Zampini } 3402e956fe4SStefano Zampini PetscFunctionReturn(0); 3412e956fe4SStefano Zampini } 3422e956fe4SStefano Zampini 3432e956fe4SStefano Zampini /*MC 3441c9cd337SJed Brown PetscFunctionListFind - Find function registered under given name 3451c9cd337SJed Brown 3461c9cd337SJed Brown Synopsis: 347aaa7dc30SBarry Smith #include <petscsys.h> 3481c9cd337SJed Brown PetscErrorCode PetscFunctionListFind(PetscFunctionList flist,const char name[],void (**fptr)(void)) 349e5c89e4eSSatish Balay 350e5c89e4eSSatish Balay Input Parameters: 3511c9cd337SJed Brown + flist - pointer to list 3521c9cd337SJed Brown - name - name registered for the function 353e5c89e4eSSatish Balay 354e5c89e4eSSatish Balay Output Parameters: 3551c9cd337SJed Brown . fptr - the function pointer if name was found, else NULL 356e5c89e4eSSatish Balay 357e5c89e4eSSatish Balay Level: developer 358e5c89e4eSSatish Balay 359db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionList`, `PetscObjectQueryFunction()` 3601c9cd337SJed Brown M*/ 3619371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscFunctionListFind_Private(PetscFunctionList fl, const char name[], void (**r)(void)) { 362140e18c1SBarry Smith PetscFunctionList entry = fl; 363bdf89e91SBarry Smith PetscBool flg; 364e5c89e4eSSatish Balay 365e5c89e4eSSatish Balay PetscFunctionBegin; 36628b400f6SJacob Faibussowitsch PetscCheck(name, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to find routine with null name"); 367e5c89e4eSSatish Balay 36802c9f0b5SLisandro Dalcin *r = NULL; 369e5c89e4eSSatish Balay while (entry) { 3709566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, entry->name, &flg)); 371bdf89e91SBarry Smith if (flg) { 372e5c89e4eSSatish Balay *r = entry->routine; 373e5c89e4eSSatish Balay PetscFunctionReturn(0); 374e5c89e4eSSatish Balay } 375e5c89e4eSSatish Balay entry = entry->next; 376e5c89e4eSSatish Balay } 377e5c89e4eSSatish Balay PetscFunctionReturn(0); 378e5c89e4eSSatish Balay } 379e5c89e4eSSatish Balay 380e5c89e4eSSatish Balay /*@ 381140e18c1SBarry Smith PetscFunctionListView - prints out contents of an PetscFunctionList 382e5c89e4eSSatish Balay 383e5c89e4eSSatish Balay Collective over MPI_Comm 384e5c89e4eSSatish Balay 385e5c89e4eSSatish Balay Input Parameters: 386e5c89e4eSSatish Balay + list - the list of functions 387e5c89e4eSSatish Balay - viewer - currently ignored 388e5c89e4eSSatish Balay 389e5c89e4eSSatish Balay Level: developer 390e5c89e4eSSatish Balay 391db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionListPrintTypes()`, `PetscFunctionList` 392e5c89e4eSSatish Balay @*/ 3939371c9d4SSatish Balay PetscErrorCode PetscFunctionListView(PetscFunctionList list, PetscViewer viewer) { 394ace3abfcSBarry Smith PetscBool iascii; 395e5c89e4eSSatish Balay 396e5c89e4eSSatish Balay PetscFunctionBegin; 397e5c89e4eSSatish Balay if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 398e5c89e4eSSatish Balay PetscValidPointer(list, 1); 3990700a824SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 400e5c89e4eSSatish Balay 4019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 40228b400f6SJacob Faibussowitsch PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only ASCII viewer supported"); 403e5c89e4eSSatish Balay 404e5c89e4eSSatish Balay while (list) { 4059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %s\n", list->name)); 406e5c89e4eSSatish Balay list = list->next; 407e5c89e4eSSatish Balay } 4089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 409e5c89e4eSSatish Balay PetscFunctionReturn(0); 410e5c89e4eSSatish Balay } 411e5c89e4eSSatish Balay 412065533a5SJed Brown /*@C 413140e18c1SBarry Smith PetscFunctionListGet - Gets an array the contains the entries in PetscFunctionList, this is used 414e5c89e4eSSatish Balay by help etc. 415e5c89e4eSSatish Balay 416d4349b43SBarry Smith Not Collective 417e5c89e4eSSatish Balay 418e5c89e4eSSatish Balay Input Parameter: 419e5c89e4eSSatish Balay . list - list of types 420e5c89e4eSSatish Balay 421d8d19677SJose E. Roman Output Parameters: 422e5c89e4eSSatish Balay + array - array of names 423e5c89e4eSSatish Balay - n - length of array 424e5c89e4eSSatish Balay 425e5c89e4eSSatish Balay Notes: 426e5c89e4eSSatish Balay This allocates the array so that must be freed. BUT the individual entries are 427e5c89e4eSSatish Balay not copied so should not be freed. 428e5c89e4eSSatish Balay 429e5c89e4eSSatish Balay Level: developer 430e5c89e4eSSatish Balay 431db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionList` 432e5c89e4eSSatish Balay @*/ 4339371c9d4SSatish Balay PetscErrorCode PetscFunctionListGet(PetscFunctionList list, const char ***array, int *n) { 434e5c89e4eSSatish Balay PetscInt count = 0; 435140e18c1SBarry Smith PetscFunctionList klist = list; 436e5c89e4eSSatish Balay 437e5c89e4eSSatish Balay PetscFunctionBegin; 438e5c89e4eSSatish Balay while (list) { 439e5c89e4eSSatish Balay list = list->next; 440e5c89e4eSSatish Balay count++; 441e5c89e4eSSatish Balay } 4429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(count + 1, (char ***)array)); 443e5c89e4eSSatish Balay count = 0; 444e5c89e4eSSatish Balay while (klist) { 445e5c89e4eSSatish Balay (*array)[count] = klist->name; 446e5c89e4eSSatish Balay klist = klist->next; 447e5c89e4eSSatish Balay count++; 448e5c89e4eSSatish Balay } 44902c9f0b5SLisandro Dalcin (*array)[count] = NULL; 450e5c89e4eSSatish Balay *n = count + 1; 451e5c89e4eSSatish Balay PetscFunctionReturn(0); 452e5c89e4eSSatish Balay } 453e5c89e4eSSatish Balay 454e5c89e4eSSatish Balay /*@C 455140e18c1SBarry Smith PetscFunctionListPrintTypes - Prints the methods available. 456e5c89e4eSSatish Balay 457e5c89e4eSSatish Balay Collective over MPI_Comm 458e5c89e4eSSatish Balay 459e5c89e4eSSatish Balay Input Parameters: 460e5c89e4eSSatish Balay + comm - the communicator (usually MPI_COMM_WORLD) 461e5c89e4eSSatish Balay . fd - file to print to, usually stdout 462e5c89e4eSSatish Balay . prefix - prefix to prepend to name (optional) 463e5c89e4eSSatish Balay . name - option string (for example, "-ksp_type") 464e5c89e4eSSatish Balay . text - short description of the object (for example, "Krylov solvers") 465e5c89e4eSSatish Balay . man - name of manual page that discusses the object (for example, "KSPCreate") 4663cc1e11dSBarry Smith . list - list of types 46744ef3d73SBarry Smith . def - default (current) value 46844ef3d73SBarry Smith - newv - new value 469e5c89e4eSSatish Balay 470e5c89e4eSSatish Balay Level: developer 471e5c89e4eSSatish Balay 472db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionList` 473e5c89e4eSSatish Balay @*/ 4749371c9d4SSatish Balay 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[]) { 475e5c89e4eSSatish Balay char p[64]; 476e5c89e4eSSatish Balay 477e5c89e4eSSatish Balay PetscFunctionBegin; 478da9f1d6bSBarry Smith if (!fd) fd = PETSC_STDOUT; 479e5c89e4eSSatish Balay 4809566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(p, "-", sizeof(p))); 4819566063dSJacob Faibussowitsch if (prefix) PetscCall(PetscStrlcat(p, prefix, sizeof(p))); 4829566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, " %s%s <now %s : formerly %s>: %s (one of)", p, name + 1, newv, def, text)); 483e5c89e4eSSatish Balay 484e5c89e4eSSatish Balay while (list) { 4859566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, " %s", list->name)); 486e5c89e4eSSatish Balay list = list->next; 487e5c89e4eSSatish Balay } 4889566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, " (%s)\n", man)); 489e5c89e4eSSatish Balay PetscFunctionReturn(0); 490e5c89e4eSSatish Balay } 491e5c89e4eSSatish Balay 492e5c89e4eSSatish Balay /*@ 493140e18c1SBarry Smith PetscFunctionListDuplicate - Creates a new list from a given object list. 494e5c89e4eSSatish Balay 495e5c89e4eSSatish Balay Input Parameters: 496e5c89e4eSSatish Balay . fl - pointer to list 497e5c89e4eSSatish Balay 498e5c89e4eSSatish Balay Output Parameters: 499e5c89e4eSSatish Balay . nl - the new list (should point to 0 to start, otherwise appends) 500e5c89e4eSSatish Balay 501e5c89e4eSSatish Balay Level: developer 502e5c89e4eSSatish Balay 503db781477SPatrick Sanan .seealso: `PetscFunctionList`, `PetscFunctionListAdd()`, `PetscFlistDestroy()` 504e5c89e4eSSatish Balay 505e5c89e4eSSatish Balay @*/ 5069371c9d4SSatish Balay PetscErrorCode PetscFunctionListDuplicate(PetscFunctionList fl, PetscFunctionList *nl) { 507e5c89e4eSSatish Balay PetscFunctionBegin; 508e5c89e4eSSatish Balay while (fl) { 5099566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(nl, fl->name, fl->routine)); 510e5c89e4eSSatish Balay fl = fl->next; 511e5c89e4eSSatish Balay } 512e5c89e4eSSatish Balay PetscFunctionReturn(0); 513e5c89e4eSSatish Balay } 514