Actual source code: slepcinit.c
slepc-main 2024-11-09
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
6: This file is part of SLEPc.
7: SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9: */
11: #include <slepc/private/slepcimpl.h>
13: #if defined(SLEPC_HAVE_HPDDM)
14: #include <petscksp.h>
15: SLEPC_EXTERN PetscErrorCode KSPCreate_HPDDM(KSP);
16: SLEPC_EXTERN PetscErrorCode PCCreate_HPDDM(PC);
17: #endif
19: /*@C
20: SlepcGetVersion - Gets the SLEPc version information in a string.
22: Not Collective
24: Input Parameter:
25: . len - length of the string
27: Output Parameter:
28: . version - version string
30: Level: intermediate
32: .seealso: SlepcGetVersionNumber()
33: @*/
34: PetscErrorCode SlepcGetVersion(char version[],size_t len)
35: {
36: PetscFunctionBegin;
37: #if (SLEPC_VERSION_RELEASE == 1)
38: PetscCall(PetscSNPrintf(version,len,"SLEPc Release Version %d.%d.%d, %s",SLEPC_VERSION_MAJOR,SLEPC_VERSION_MINOR,SLEPC_VERSION_SUBMINOR,SLEPC_VERSION_DATE));
39: #else
40: PetscCall(PetscSNPrintf(version,len,"SLEPc Development GIT revision: %s GIT Date: %s",SLEPC_VERSION_GIT,SLEPC_VERSION_DATE_GIT));
41: #endif
42: PetscFunctionReturn(PETSC_SUCCESS);
43: }
45: /*@
46: SlepcGetVersionNumber - Gets the SLEPc version information from the library.
48: Not Collective
50: Output Parameters:
51: + major - the major version
52: . minor - the minor version
53: . subminor - the subminor version (patch number)
54: - release - indicates the library is from a release
56: Notes:
57: Pass NULL in any argument that is not requested.
59: The C macros SLEPC_VERSION_MAJOR, SLEPC_VERSION_MINOR, SLEPC_VERSION_SUBMINOR,
60: SLEPC_VERSION_RELEASE provide the information at compile time. This can be used to confirm
61: that the shared library being loaded at runtime has the appropriate version updates.
63: This function can be called before SlepcInitialize().
65: Level: intermediate
67: .seealso: SlepcGetVersion(), SlepcInitialize()
68: @*/
69: PetscErrorCode SlepcGetVersionNumber(PetscInt *major,PetscInt *minor,PetscInt *subminor,PetscInt *release)
70: {
71: if (major) *major = SLEPC_VERSION_MAJOR;
72: if (minor) *minor = SLEPC_VERSION_MINOR;
73: if (subminor) *subminor = SLEPC_VERSION_SUBMINOR;
74: if (release) *release = SLEPC_VERSION_RELEASE;
75: return PETSC_SUCCESS;
76: }
78: /*
79: SlepcPrintVersion - Prints SLEPc version info.
81: Collective
82: */
83: static PetscErrorCode SlepcPrintVersion(MPI_Comm comm)
84: {
85: char version[256];
87: PetscFunctionBegin;
88: PetscCall(SlepcGetVersion(version,256));
89: PetscCall((*PetscHelpPrintf)(comm,"%s\n",version));
90: PetscCall((*PetscHelpPrintf)(comm,SLEPC_AUTHOR_INFO));
91: PetscCall((*PetscHelpPrintf)(comm,"See https://slepc.upv.es/documentation/ for help.\n"));
92: PetscCall((*PetscHelpPrintf)(comm,"SLEPc libraries linked from %s\n",SLEPC_LIB_DIR));
93: PetscFunctionReturn(PETSC_SUCCESS);
94: }
96: /*
97: SlepcPrintHelpIntro - Prints introductory SLEPc help info.
99: Collective
100: */
101: static PetscErrorCode SlepcPrintHelpIntro(MPI_Comm comm)
102: {
103: PetscFunctionBegin;
104: PetscCall((*PetscHelpPrintf)(comm,"SLEPc help information includes that for the PETSc libraries, which provide\n"));
105: PetscCall((*PetscHelpPrintf)(comm,"low-level system infrastructure and linear algebra tools.\n"));
106: PetscCall((*PetscHelpPrintf)(comm,"----------------------------------------\n"));
107: PetscFunctionReturn(PETSC_SUCCESS);
108: }
110: /* ------------------------Nasty global variables -------------------------------*/
111: /*
112: Indicates whether SLEPc started PETSc, or whether it was
113: already started before SLEPc was initialized.
114: */
115: PetscBool SlepcBeganPetsc = PETSC_FALSE;
116: PetscBool SlepcInitializeCalled = PETSC_FALSE;
117: PetscBool SlepcFinalizeCalled = PETSC_FALSE;
119: #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES)
120: static PetscErrorCode SlepcLoadDynamicLibrary(const char *name,PetscBool *found)
121: {
122: char libs[PETSC_MAX_PATH_LEN],dlib[PETSC_MAX_PATH_LEN];
124: PetscFunctionBegin;
125: PetscCall(PetscStrcpy(libs,SLEPC_LIB_DIR));
126: PetscCall(PetscStrlcat(libs,"/libslepc",sizeof(libs)));
127: PetscCall(PetscStrlcat(libs,name,sizeof(libs)));
128: #if defined(PETSC_LIB_NAME_SUFFIX)
129: PetscCall(PetscStrlcat(libs,PETSC_LIB_NAME_SUFFIX,sizeof(libs)));
130: #endif
131: PetscCall(PetscDLLibraryRetrieve(PETSC_COMM_WORLD,libs,dlib,sizeof(dlib),found));
132: if (*found) PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,dlib));
133: PetscFunctionReturn(PETSC_SUCCESS);
134: }
135: #endif
137: #if defined(PETSC_USE_SINGLE_LIBRARY) && !(defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES))
138: SLEPC_EXTERN PetscErrorCode STInitializePackage(void);
139: SLEPC_EXTERN PetscErrorCode DSInitializePackage(void);
140: SLEPC_EXTERN PetscErrorCode FNInitializePackage(void);
141: SLEPC_EXTERN PetscErrorCode BVInitializePackage(void);
142: SLEPC_EXTERN PetscErrorCode RGInitializePackage(void);
143: SLEPC_EXTERN PetscErrorCode EPSInitializePackage(void);
144: SLEPC_EXTERN PetscErrorCode SVDInitializePackage(void);
145: SLEPC_EXTERN PetscErrorCode PEPInitializePackage(void);
146: SLEPC_EXTERN PetscErrorCode NEPInitializePackage(void);
147: SLEPC_EXTERN PetscErrorCode MFNInitializePackage(void);
148: SLEPC_EXTERN PetscErrorCode LMEInitializePackage(void);
149: #endif
151: /*
152: SlepcInitialize_DynamicLibraries - Adds the default dynamic link libraries to the
153: search path.
154: */
155: PetscErrorCode SlepcInitialize_DynamicLibraries(void)
156: {
157: PetscBool preload = PETSC_FALSE;
159: PetscFunctionBegin;
160: #if defined(PETSC_HAVE_THREADSAFETY)
161: /* These must be all initialized here because it is not safe for individual threads to call these initialize routines */
162: preload = PETSC_TRUE;
163: #endif
165: PetscCall(PetscOptionsGetBool(NULL,NULL,"-library_preload",&preload,NULL));
166: if (preload) {
167: #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES)
168: PetscBool found;
169: #if defined(PETSC_USE_SINGLE_LIBRARY)
170: PetscCall(SlepcLoadDynamicLibrary("",&found));
171: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc dynamic library. You cannot move the dynamic libraries!");
172: #else
173: PetscCall(SlepcLoadDynamicLibrary("sys",&found));
174: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc sys dynamic library. You cannot move the dynamic libraries!");
175: PetscCall(SlepcLoadDynamicLibrary("eps",&found));
176: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc EPS dynamic library. You cannot move the dynamic libraries!");
177: PetscCall(SlepcLoadDynamicLibrary("pep",&found));
178: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc PEP dynamic library. You cannot move the dynamic libraries!");
179: PetscCall(SlepcLoadDynamicLibrary("nep",&found));
180: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc NEP dynamic library. You cannot move the dynamic libraries!");
181: PetscCall(SlepcLoadDynamicLibrary("svd",&found));
182: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc SVD dynamic library. You cannot move the dynamic libraries!");
183: PetscCall(SlepcLoadDynamicLibrary("mfn",&found));
184: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc MFN dynamic library. You cannot move the dynamic libraries!");
185: PetscCall(SlepcLoadDynamicLibrary("lme",&found));
186: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc LME dynamic library. You cannot move the dynamic libraries!");
187: #endif
188: #else /* defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) */
189: #if defined(PETSC_USE_SINGLE_LIBRARY)
190: PetscCall(STInitializePackage());
191: PetscCall(DSInitializePackage());
192: PetscCall(FNInitializePackage());
193: PetscCall(BVInitializePackage());
194: PetscCall(RGInitializePackage());
195: PetscCall(EPSInitializePackage());
196: PetscCall(SVDInitializePackage());
197: PetscCall(PEPInitializePackage());
198: PetscCall(NEPInitializePackage());
199: PetscCall(MFNInitializePackage());
200: PetscCall(LMEInitializePackage());
201: #else
202: SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Cannot use -library_preload with multiple static SLEPc libraries");
203: #endif
204: #endif /* defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) */
205: }
207: #if defined(SLEPC_HAVE_HPDDM)
208: PetscCall(KSPRegister(KSPHPDDM,KSPCreate_HPDDM));
209: PetscCall(PCRegister(PCHPDDM,PCCreate_HPDDM));
210: #endif
211: PetscFunctionReturn(PETSC_SUCCESS);
212: }
214: PetscErrorCode SlepcCitationsInitialize(void)
215: {
216: PetscFunctionBegin;
217: PetscCall(PetscCitationsRegister("@Article{slepc-toms,\n"
218: " author = \"Vicente Hernandez and Jose E. Roman and Vicente Vidal\",\n"
219: " title = \"{SLEPc}: A Scalable and Flexible Toolkit for the Solution of Eigenvalue Problems\",\n"
220: " journal = \"{ACM} Trans. Math. Software\",\n"
221: " volume = \"31\",\n"
222: " number = \"3\",\n"
223: " pages = \"351--362\",\n"
224: " year = \"2005\",\n"
225: " doi = \"https://doi.org/10.1145/1089014.1089019\"\n"
226: "}\n",NULL));
227: PetscCall(PetscCitationsRegister("@TechReport{slepc-manual,\n"
228: " author = \"J. E. Roman and C. Campos and L. Dalcin and E. Romero and A. Tomas\",\n"
229: " title = \"{SLEPc} Users Manual\",\n"
230: " number = \"DSIC-II/24/02 - Revision 3.22\",\n"
231: " institution = \"D. Sistemes Inform\\`atics i Computaci\\'o, Universitat Polit\\`ecnica de Val\\`encia\",\n"
232: " year = \"2024\"\n"
233: "}\n",NULL));
234: PetscFunctionReturn(PETSC_SUCCESS);
235: }
237: /*@C
238: SlepcInitialize - Initializes the SLEPc library. SlepcInitialize() calls
239: PetscInitialize() if that has not been called yet, so this routine should
240: always be called near the beginning of your program.
242: Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set
244: Input Parameters:
245: + argc - count of number of command line arguments
246: . args - the command line arguments
247: . file - [optional] PETSc database file, defaults to ~username/.petscrc
248: (use NULL for default)
249: - help - [optional] Help message to print, use NULL for no message
251: Fortran Notes:
252: Fortran syntax is very similar to that of PetscInitialize()
254: Level: beginner
256: .seealso: SlepcFinalize(), PetscInitialize(), SlepcInitializeFortran()
257: @*/
258: PetscErrorCode SlepcInitialize(int *argc,char ***args,const char file[],const char help[])
259: {
260: PetscBool flg;
262: PetscFunctionBegin;
263: if (SlepcInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
264: PetscCall(PetscSetHelpVersionFunctions(SlepcPrintHelpIntro,SlepcPrintVersion));
265: PetscCall(PetscInitialized(&flg));
266: if (!flg) {
267: PetscCall(PetscInitialize(argc,args,file,help));
268: SlepcBeganPetsc = PETSC_TRUE;
269: }
271: PetscCall(SlepcCitationsInitialize());
273: /* Load the dynamic libraries (on machines that support them), this registers all the solvers etc. */
274: PetscCall(SlepcInitialize_DynamicLibraries());
276: SlepcInitializeCalled = PETSC_TRUE;
277: SlepcFinalizeCalled = PETSC_FALSE;
278: PetscCall(PetscInfo(0,"SLEPc successfully started\n"));
279: PetscFunctionReturn(PETSC_SUCCESS);
280: }
282: /*@C
283: SlepcFinalize - Checks for options to be called at the conclusion
284: of the SLEPc program and calls PetscFinalize().
286: Collective on PETSC_COMM_WORLD
288: Level: beginner
290: .seealso: SlepcInitialize(), PetscFinalize()
291: @*/
292: PetscErrorCode SlepcFinalize(void)
293: {
294: PetscFunctionBegin;
295: if (PetscUnlikely(!SlepcInitializeCalled)) {
296: fprintf(PETSC_STDOUT,"SlepcInitialize() must be called before SlepcFinalize()\n");
297: PetscStackClearTop;
298: return PETSC_ERR_ARG_WRONGSTATE;
299: }
300: PetscCall(PetscInfo(NULL,"SlepcFinalize() called\n"));
301: if (SlepcBeganPetsc) {
302: PetscCall(PetscFinalize());
303: SlepcBeganPetsc = PETSC_FALSE;
304: }
305: SlepcInitializeCalled = PETSC_FALSE;
306: SlepcFinalizeCalled = PETSC_TRUE;
307: PetscStackClearTop;
308: return PETSC_SUCCESS;
309: }
311: /*@C
312: SlepcInitializeNoArguments - Calls SlepcInitialize() from C/C++ without
313: the command line arguments.
315: Collective
317: Level: advanced
319: .seealso: SlepcInitialize(), SlepcInitializeFortran()
320: @*/
321: PetscErrorCode SlepcInitializeNoArguments(void)
322: {
323: int argc = 0;
324: char **args = NULL;
326: PetscFunctionBegin;
327: PetscCall(SlepcInitialize(&argc,&args,NULL,NULL));
328: PetscFunctionReturn(PETSC_SUCCESS);
329: }
331: /*@
332: SlepcInitialized - Determine whether SLEPc is initialized.
334: Output Parameter:
335: . isInitialized - the result
337: Level: beginner
339: .seealso: SlepcInitialize(), SlepcInitializeFortran()
340: @*/
341: PetscErrorCode SlepcInitialized(PetscBool *isInitialized)
342: {
343: PetscFunctionBegin;
344: *isInitialized = SlepcInitializeCalled;
345: PetscFunctionReturn(PETSC_SUCCESS);
346: }
348: /*@
349: SlepcFinalized - Determine whether SlepcFinalize() has been called.
351: Output Parameter:
352: . isFinalized - the result
354: Level: developer
356: .seealso: SlepcFinalize()
357: @*/
358: PetscErrorCode SlepcFinalized(PetscBool *isFinalized)
359: {
360: PetscFunctionBegin;
361: *isFinalized = SlepcFinalizeCalled;
362: PetscFunctionReturn(PETSC_SUCCESS);
363: }
365: PETSC_EXTERN PetscBool PetscBeganMPI;
367: /*@C
368: SlepcInitializeNoPointers - Calls SlepcInitialize() from C/C++ without the pointers
369: to argc and args (analogue to PetscInitializeNoPointers).
371: Collective
373: Input Parameters:
374: + argc - count of number of command line arguments
375: . args - the command line arguments
376: . file - [optional] PETSc database file, defaults to ~username/.petscrc
377: (use NULL for default)
378: - help - [optional] Help message to print, use NULL for no message
380: Level: advanced
382: .seealso: SlepcInitialize()
383: @*/
384: PetscErrorCode SlepcInitializeNoPointers(int argc,char **args,const char *file,const char *help)
385: {
386: int myargc = argc;
387: char **myargs = args;
389: PetscFunctionBegin;
390: PetscCall(SlepcInitialize(&myargc,&myargs,file,help));
391: PetscCall(PetscPopSignalHandler());
392: PetscBeganMPI = PETSC_FALSE;
393: PetscFunctionReturn(PETSC_SUCCESS);
394: }