xref: /petsc/include/petscsys.h (revision b12e77b2dafe08a3135b110b3db60a43ac3be1c7)
1 /*
2     Provides access to system related and general utility routines.
3 */
4 #if !defined(__PETSCSYS_H)
5 #define __PETSCSYS_H
6 #include "petsc.h"
7 PETSC_EXTERN_CXX_BEGIN
8 
9 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetArchType(char[],size_t);
10 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetHostName(char[],size_t);
11 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetUserName(char[],size_t);
12 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetProgramName(char[],size_t);
13 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSetProgramName(const char[]);
14 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetDate(char[],size_t);
15 
16 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSortInt(PetscInt,PetscInt[]);
17 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscSortIntWithPermutation(PetscInt,const PetscInt[],PetscInt[]);
18 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscSortStrWithPermutation(PetscInt,const char*[],PetscInt[]);
19 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscSortIntWithArray(PetscInt,PetscInt[],PetscInt[]);
20 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscSortIntWithScalarArray(PetscInt,PetscInt[],PetscScalar[]);
21 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscSortReal(PetscInt,PetscReal[]);
22 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscSortRealWithPermutation(PetscInt,const PetscReal[],PetscInt[]);
23 
24 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscSetDisplay(void);
25 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscGetDisplay(char[],size_t);
26 
27 extern PetscCookie PETSC_DLLEXPORT PETSC_RANDOM_COOKIE;
28 
29 typedef enum {RANDOM_DEFAULT,RANDOM_DEFAULT_REAL,RANDOM_DEFAULT_IMAGINARY} PetscRandomType;
30 
31 /*S
32      PetscRandom - Abstract PETSc object that manages generating random numbers
33 
34    Level: intermediate
35 
36   Concepts: random numbers
37 
38 .seealso:  PetscRandomCreate(), PetscRandomGetValue()
39 S*/
40 typedef struct _p_PetscRandom*   PetscRandom;
41 
42 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscRandomCreate(MPI_Comm,PetscRandomType,PetscRandom*);
43 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscRandomGetValue(PetscRandom,PetscScalar*);
44 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscRandomGetInterval(PetscRandom,PetscScalar*,PetscScalar*);
45 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscRandomSetInterval(PetscRandom,PetscScalar,PetscScalar);
46 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscRandomSetSeed(PetscRandom,unsigned long);
47 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscRandomGetSeed(PetscRandom,unsigned long *);
48 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscRandomSeed(PetscRandom);
49 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscRandomDestroy(PetscRandom);
50 
51 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetFullPath(const char[],char[],size_t);
52 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetRelativePath(const char[],char[],size_t);
53 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetWorkingDirectory(char[],size_t);
54 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetRealPath(char[],char[]);
55 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetHomeDirectory(char[],size_t);
56 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscTestFile(const char[],char,PetscTruth*);
57 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscTestDirectory(const char[],char,PetscTruth*);
58 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscBinaryRead(int,void*,PetscInt,PetscDataType);
59 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedBinaryRead(MPI_Comm,int,void*,PetscInt,PetscDataType);
60 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedBinaryWrite(MPI_Comm,int,void*,PetscInt,PetscDataType,PetscTruth);
61 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscBinaryWrite(int,void*,PetscInt,PetscDataType,PetscTruth);
62 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscBinaryOpen(const char[],int,int *);
63 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscBinaryClose(int);
64 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSharedTmp(MPI_Comm,PetscTruth *);
65 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSharedWorkingDirectory(MPI_Comm,PetscTruth *);
66 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetTmp(MPI_Comm,char *,size_t);
67 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscFileRetrieve(MPI_Comm,const char *,char *,size_t,PetscTruth*);
68 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLs(MPI_Comm,const char[],char*,size_t,PetscTruth*);
69 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryCCAAppend(MPI_Comm,PetscDLLibraryList*,const char[]);
70 
71 /*
72    In binary files variables are stored using the following lengths,
73   regardless of how they are stored in memory on any one particular
74   machine. Use these rather then sizeof() in computing sizes for
75   PetscBinarySeek().
76 */
77 #define PETSC_BINARY_INT_SIZE    (32/8)
78 #define PETSC_BINARY_FLOAT_SIZE  (32/8)
79 #define PETSC_BINARY_CHAR_SIZE    (8/8)
80 #define PETSC_BINARY_SHORT_SIZE  (16/8)
81 #define PETSC_BINARY_DOUBLE_SIZE (64/8)
82 #define PETSC_BINARY_SCALAR_SIZE sizeof(PetscScalar)
83 
84 /*E
85   PetscBinarySeekType - argument to PetscBinarySeek()
86 
87   Level: advanced
88 
89 .seealso: PetscBinarySeek(), PetscSynchronizedBinarySeek()
90 E*/
91 typedef enum {PETSC_BINARY_SEEK_SET = 0,PETSC_BINARY_SEEK_CUR = 1,PETSC_BINARY_SEEK_END = 2} PetscBinarySeekType;
92 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscBinarySeek(int,off_t,PetscBinarySeekType,off_t*);
93 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedBinarySeek(MPI_Comm,int,off_t,PetscBinarySeekType,off_t*);
94 
95 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSetDebugger(const char[],PetscTruth);
96 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSetDefaultDebugger(void);
97 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSetDebuggerFromString(char*);
98 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscAttachDebugger(void);
99 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscStopForDebugger(void);
100 
101 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGatherNumberOfMessages(MPI_Comm,PetscMPIInt*,PetscMPIInt*,PetscMPIInt*);
102 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGatherMessageLengths(MPI_Comm,PetscMPIInt,PetscMPIInt,PetscMPIInt*,PetscMPIInt**,PetscMPIInt**);
103 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGatherMessageLengths2(MPI_Comm,PetscMPIInt,PetscMPIInt,PetscMPIInt*,PetscMPIInt*,PetscMPIInt**,PetscMPIInt**,PetscMPIInt**);
104 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscPostIrecvInt(MPI_Comm,PetscMPIInt,PetscMPIInt,PetscMPIInt*,PetscMPIInt*,PetscInt***,MPI_Request**);
105 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscPostIrecvScalar(MPI_Comm,PetscMPIInt,PetscMPIInt,PetscMPIInt*,PetscMPIInt*,PetscScalar***,MPI_Request**);
106 
107 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscSSEIsEnabled(MPI_Comm,PetscTruth *,PetscTruth *);
108 
109 /* Parallel communication routines */
110 /*E
111   InsertMode - Whether entries are inserted or added into vectors or matrices
112 
113   Level: beginner
114 
115 .seealso: VecSetValues(), MatSetValues(), VecSetValue(), VecSetValuesBlocked(),
116           VecSetValuesLocal(), VecSetValuesBlockedLocal(), MatSetValuesBlocked(),
117           MatSetValuesBlockedLocal(), MatSetValuesLocal(), VecScatterBegin(), VecScatterEnd()
118 E*/
119 typedef enum {NOT_SET_VALUES, INSERT_VALUES, ADD_VALUES, MAX_VALUES} InsertMode;
120 
121 /*MC
122     INSERT_VALUES - Put a value into a vector or matrix, overwrites any previous value
123 
124     Level: beginner
125 
126 .seealso: InsertMode, VecSetValues(), MatSetValues(), VecSetValue(), VecSetValuesBlocked(),
127           VecSetValuesLocal(), VecSetValuesBlockedLocal(), MatSetValuesBlocked(), ADD_VALUES, INSERT_VALUES,
128           MatSetValuesBlockedLocal(), MatSetValuesLocal(), VecScatterBegin(), VecScatterEnd()
129 
130 M*/
131 
132 /*MC
133     ADD_VALUES - Adds a value into a vector or matrix, if there previously was no value, just puts the
134                 value into that location
135 
136     Level: beginner
137 
138 .seealso: InsertMode, VecSetValues(), MatSetValues(), VecSetValue(), VecSetValuesBlocked(),
139           VecSetValuesLocal(), VecSetValuesBlockedLocal(), MatSetValuesBlocked(), ADD_VALUES, INSERT_VALUES,
140           MatSetValuesBlockedLocal(), MatSetValuesLocal(), VecScatterBegin(), VecScatterEnd()
141 
142 M*/
143 
144 /*MC
145     MAX_VALUES - Puts the maximum of the scattered/gathered value and the current value into each location
146 
147     Level: beginner
148 
149 .seealso: InsertMode, VecScatterBegin(), VecScatterEnd(), ADD_VALUES, INSERT_VALUES
150 
151 M*/
152 
153 /*E
154   ScatterMode - Determines the direction of a scatter
155 
156   Level: beginner
157 
158 .seealso: VecScatter, VecScatterBegin(), VecScatterEnd()
159 E*/
160 typedef enum {SCATTER_FORWARD=0, SCATTER_REVERSE=1, SCATTER_FORWARD_LOCAL=2, SCATTER_REVERSE_LOCAL=3, SCATTER_LOCAL=2} ScatterMode;
161 
162 /*MC
163     SCATTER_FORWARD - Scatters the values as dictated by the VecScatterCreate() call
164 
165     Level: beginner
166 
167 .seealso: VecScatter, ScatterMode, VecScatterCreate(), VecScatterBegin(), VecScatterEnd(), SCATTER_REVERSE, SCATTER_FORWARD_LOCAL,
168           SCATTER_REVERSE_LOCAL
169 
170 M*/
171 
172 /*MC
173     SCATTER_REVERSE - Moves the values in the opposite direction then the directions indicated in
174          in the VecScatterCreate()
175 
176     Level: beginner
177 
178 .seealso: VecScatter, ScatterMode, VecScatterCreate(), VecScatterBegin(), VecScatterEnd(), SCATTER_FORWARD, SCATTER_FORWARD_LOCAL,
179           SCATTER_REVERSE_LOCAL
180 
181 M*/
182 
183 /*MC
184     SCATTER_FORWARD_LOCAL - Scatters the values as dictated by the VecScatterCreate() call except NO parallel communication
185        is done. Any variables that have be moved between processes are ignored
186 
187     Level: developer
188 
189 .seealso: VecScatter, ScatterMode, VecScatterCreate(), VecScatterBegin(), VecScatterEnd(), SCATTER_REVERSE, SCATTER_FORWARD,
190           SCATTER_REVERSE_LOCAL
191 
192 M*/
193 
194 /*MC
195     SCATTER_REVERSE_LOCAL - Moves the values in the opposite direction then the directions indicated in
196          in the VecScatterCreate()  except NO parallel communication
197        is done. Any variables that have be moved between processes are ignored
198 
199     Level: developer
200 
201 .seealso: VecScatter, ScatterMode, VecScatterCreate(), VecScatterBegin(), VecScatterEnd(), SCATTER_FORWARD, SCATTER_FORWARD_LOCAL,
202           SCATTER_REVERSE
203 
204 M*/
205 
206 /*
207   Create and initialize a linked list
208   Input Parameters:
209     idx_start - starting index of the list
210     lnk_max   - max value of lnk indicating the end of the list
211     nlnk      - max length of the list
212   Output Parameters:
213     lnk       - list initialized
214     bt        - PetscBT (bitarray) with all bits set to false
215 */
216 #define PetscLLCreate(idx_start,lnk_max,nlnk,lnk,bt) \
217   (PetscMalloc(nlnk*sizeof(PetscInt),&lnk) || PetscBTCreate(nlnk,bt) || PetscBTMemzero(nlnk,bt) || (lnk[idx_start] = lnk_max,0))
218 
219 /*
220   Add a index set into a sorted linked list
221   Input Parameters:
222     nidx      - number of input indices
223     indices   - interger array
224     idx_start - starting index of the list
225     lnk       - linked list(an integer array) that is created
226     bt        - PetscBT (bitarray), bt[idx]=true marks idx is in lnk
227   output Parameters:
228     nlnk      - number of newly added indices
229     lnk       - the sorted(increasing order) linked list containing new and non-redundate entries from indices
230     bt        - updated PetscBT (bitarray)
231 */
232 #define PetscLLAdd(nidx,indices,idx_start,nlnk,lnk,bt) 0;\
233 {\
234   PetscInt _k,_entry,_location,_lnkdata;\
235   nlnk     = 0;\
236   _lnkdata = idx_start;\
237   for (_k=0; _k<nidx; _k++){\
238     _entry = indices[_k];\
239     if (!PetscBTLookupSet(bt,_entry)){  /* new entry */\
240       /* search for insertion location */\
241       /* start from the beginning if _entry < previous _entry */\
242       if (_k && _entry < _lnkdata) _lnkdata  = idx_start;\
243       do {\
244         _location = _lnkdata;\
245         _lnkdata  = lnk[_location];\
246       } while (_entry > _lnkdata);\
247       /* insertion location is found, add entry into lnk */\
248       lnk[_location] = _entry;\
249       lnk[_entry]    = _lnkdata;\
250       nlnk++;\
251       _lnkdata = _entry; /* next search starts from here if next_entry > _entry */\
252     }\
253   }\
254 }
255 
256 /*
257   Add a SORTED index set into a sorted linked list
258   Input Parameters:
259     nidx      - number of input indices
260     indices   - sorted interger array
261     idx_start - starting index of the list
262     lnk       - linked list(an integer array) that is created
263     bt        - PetscBT (bitarray), bt[idx]=true marks idx is in lnk
264   output Parameters:
265     nlnk      - number of newly added indices
266     lnk       - the sorted(increasing order) linked list containing new and non-redundate entries from indices
267     bt        - updated PetscBT (bitarray)
268 */
269 #define PetscLLAddSorted(nidx,indices,idx_start,nlnk,lnk,bt) 0;\
270 {\
271   PetscInt _k,_entry,_location,_lnkdata;\
272   nlnk      = 0;\
273   _lnkdata  = idx_start;\
274   for (_k=0; _k<nidx; _k++){\
275     _entry = indices[_k];\
276     if (!PetscBTLookupSet(bt,_entry)){  /* new entry */\
277       /* search for insertion location */\
278       do {\
279         _location = _lnkdata;\
280         _lnkdata  = lnk[_location];\
281       } while (_entry > _lnkdata);\
282       /* insertion location is found, add entry into lnk */\
283       lnk[_location] = _entry;\
284       lnk[_entry]    = _lnkdata;\
285       nlnk++;\
286       _lnkdata = _entry; /* next search starts from here */\
287     }\
288   }\
289 }
290 
291 /*
292   Add a SORTED index set into a sorted linked list used for LUFactorSymbolic()
293   Same as PetscLLAddSorted() with an additional operation:
294        count the number of input indices that are no larger than 'diag'
295   Input Parameters:
296     nidx      - number of input indices
297     indices   - sorted interger array
298     idx_start - starting index of the list
299     lnk       - linked list(an integer array) that is created
300     bt        - PetscBT (bitarray), bt[idx]=true marks idx is in lnk
301     diag      - index of the active row in LUFactorSymbolic
302   output Parameters:
303     nlnk      - number of newly added indices
304     lnk       - the sorted(increasing order) linked list containing new and non-redundate entries from indices
305     bt        - updated PetscBT (bitarray)
306     nzbd      - number of input indices that are no larger than 'diag'
307 */
308 #define PetscLLAddSortedLU(nidx,indices,idx_start,nlnk,lnk,bt,diag,nzbd) 0;\
309 {\
310   PetscInt _k,_entry,_location,_lnkdata;\
311   nlnk     = 0;\
312   _lnkdata = idx_start;\
313   nzbd     = 0;\
314   for (_k=0; _k<nidx; _k++){\
315     _entry = indices[_k];\
316     if (_entry <= diag) nzbd++;\
317     if (!PetscBTLookupSet(bt,_entry)){  /* new entry */\
318       /* search for insertion location */\
319       do {\
320         _location = _lnkdata;\
321         _lnkdata  = lnk[_location];\
322       } while (_entry > _lnkdata);\
323       /* insertion location is found, add entry into lnk */\
324       lnk[_location] = _entry;\
325       lnk[_entry]    = _lnkdata;\
326       nlnk++;\
327       _lnkdata = _entry; /* next search starts from here */\
328     }\
329   }\
330 }
331 
332 /*
333   Copy data on the list into an array, then initialize the list
334   Input Parameters:
335     idx_start - starting index of the list
336     lnk_max   - max value of lnk indicating the end of the list
337     nlnk      - number of data on the list to be copied
338     lnk       - linked list
339     bt        - PetscBT (bitarray), bt[idx]=true marks idx is in lnk
340   output Parameters:
341     indices   - array that contains the copied data
342     lnk       - linked list that is cleaned and initialize
343     bt        - PetscBT (bitarray) with all bits set to false
344 */
345 #define PetscLLClean(idx_start,lnk_max,nlnk,lnk,indices,bt) 0;\
346 {\
347   PetscInt _j,_idx=idx_start;\
348   for (_j=0; _j<nlnk; _j++){\
349     _idx = lnk[_idx];\
350     *(indices+_j) = _idx;\
351     ierr = PetscBTClear(bt,_idx);CHKERRQ(ierr);\
352   }\
353   lnk[idx_start] = lnk_max;\
354 }
355 /*
356   Free memories used by the list
357 */
358 #define PetscLLDestroy(lnk,bt) (PetscFree(lnk) || PetscBTDestroy(bt))
359 
360 /* Routines below are used for incomplete matrix factorization */
361 /*
362   Create and initialize a linked list and its levels
363   Input Parameters:
364     idx_start - starting index of the list
365     lnk_max   - max value of lnk indicating the end of the list
366     nlnk      - max length of the list
367   Output Parameters:
368     lnk       - list initialized
369     lnk_lvl   - array of size nlnk for storing levels of lnk
370     bt        - PetscBT (bitarray) with all bits set to false
371 */
372 #define PetscIncompleteLLCreate(idx_start,lnk_max,nlnk,lnk,lnk_lvl,bt)\
373   (PetscMalloc(2*nlnk*sizeof(PetscInt),&lnk) || PetscBTCreate(nlnk,bt) || PetscBTMemzero(nlnk,bt) || (lnk[idx_start] = lnk_max,lnk_lvl = lnk + nlnk,0))
374 
375 /*
376   Initialize a sorted linked list used for ILU and ICC
377   Input Parameters:
378     nidx      - number of input idx
379     idx       - interger array used for storing column indices
380     idx_start - starting index of the list
381     perm      - indices of an IS
382     lnk       - linked list(an integer array) that is created
383     lnklvl    - levels of lnk
384     bt        - PetscBT (bitarray), bt[idx]=true marks idx is in lnk
385   output Parameters:
386     nlnk     - number of newly added idx
387     lnk      - the sorted(increasing order) linked list containing new and non-redundate entries from idx
388     lnklvl   - levels of lnk
389     bt       - updated PetscBT (bitarray)
390 */
391 #define PetscIncompleteLLInit(nidx,idx,idx_start,perm,nlnk,lnk,lnklvl,bt) 0;\
392 {\
393   PetscInt _k,_entry,_location,_lnkdata;\
394   nlnk     = 0;\
395   _lnkdata = idx_start;\
396   for (_k=0; _k<nidx; _k++){\
397     _entry = perm[idx[_k]];\
398     if (!PetscBTLookupSet(bt,_entry)){  /* new entry */\
399       /* search for insertion location */\
400       if (_k && _entry < _lnkdata) _lnkdata  = idx_start;\
401       do {\
402         _location = _lnkdata;\
403         _lnkdata  = lnk[_location];\
404       } while (_entry > _lnkdata);\
405       /* insertion location is found, add entry into lnk */\
406       lnk[_location]  = _entry;\
407       lnk[_entry]     = _lnkdata;\
408       lnklvl[_entry] = 0;\
409       nlnk++;\
410       _lnkdata = _entry; /* next search starts from here if next_entry > _entry */\
411     }\
412   }\
413 }
414 
415 /*
416   Add a SORTED index set into a sorted linked list for ILU
417   Input Parameters:
418     nidx      - number of input indices
419     idx       - sorted interger array used for storing column indices
420     level     - level of fill, e.g., ICC(level)
421     idxlvl    - level of idx
422     idx_start - starting index of the list
423     lnk       - linked list(an integer array) that is created
424     lnklvl    - levels of lnk
425     bt        - PetscBT (bitarray), bt[idx]=true marks idx is in lnk
426     prow      - the row number of idx
427   output Parameters:
428     nlnk     - number of newly added idx
429     lnk      - the sorted(increasing order) linked list containing new and non-redundate entries from idx
430     lnklvl   - levels of lnk
431     bt       - updated PetscBT (bitarray)
432 
433   Note: the level of factor(i,j) is set as lvl(i,j) = min{ lvl(i,j), lvl(i,prow)+lvl(prow,j)+1)
434         where idx = non-zero columns of U(prow,prow+1:n-1), prow<i
435 */
436 #define PetscILULLAddSorted(nidx,idx,level,idxlvl,idx_start,nlnk,lnk,lnklvl,bt,lnklvl_prow) 0;\
437 {\
438   PetscInt _k,_entry,_location,_lnkdata,_incrlev,_lnklvl_prow=lnklvl[prow];\
439   nlnk     = 0;\
440   _lnkdata = idx_start;\
441   for (_k=0; _k<nidx; _k++){\
442     _incrlev = idxlvl[_k] + _lnklvl_prow + 1;\
443     if (_incrlev > level) continue;\
444     _entry = idx[_k];\
445     if (!PetscBTLookupSet(bt,_entry)){  /* new entry */\
446       /* search for insertion location */\
447       do {\
448         _location = _lnkdata;\
449         _lnkdata  = lnk[_location];\
450       } while (_entry > _lnkdata);\
451       /* insertion location is found, add entry into lnk */\
452       lnk[_location]  = _entry;\
453       lnk[_entry]     = _lnkdata;\
454       lnklvl[_entry] = _incrlev;\
455       nlnk++;\
456       _lnkdata = _entry; /* next search starts from here if next_entry > _entry */\
457     } else { /* existing entry: update lnklvl */\
458       if (lnklvl[_entry] > _incrlev) lnklvl[_entry] = _incrlev;\
459     }\
460   }\
461 }
462 
463 /*
464   Add a index set into a sorted linked list
465   Input Parameters:
466     nidx      - number of input idx
467     idx   - interger array used for storing column indices
468     level     - level of fill, e.g., ICC(level)
469     idxlvl - level of idx
470     idx_start - starting index of the list
471     lnk       - linked list(an integer array) that is created
472     lnklvl   - levels of lnk
473     bt        - PetscBT (bitarray), bt[idx]=true marks idx is in lnk
474   output Parameters:
475     nlnk      - number of newly added idx
476     lnk       - the sorted(increasing order) linked list containing new and non-redundate entries from idx
477     lnklvl   - levels of lnk
478     bt        - updated PetscBT (bitarray)
479 */
480 #define PetscIncompleteLLAdd(nidx,idx,level,idxlvl,idx_start,nlnk,lnk,lnklvl,bt) 0;\
481 {\
482   PetscInt _k,_entry,_location,_lnkdata,_incrlev;\
483   nlnk     = 0;\
484   _lnkdata = idx_start;\
485   for (_k=0; _k<nidx; _k++){\
486     _incrlev = idxlvl[_k] + 1;\
487     if (_incrlev > level) continue;\
488     _entry = idx[_k];\
489     if (!PetscBTLookupSet(bt,_entry)){  /* new entry */\
490       /* search for insertion location */\
491       if (_k && _entry < _lnkdata) _lnkdata  = idx_start;\
492       do {\
493         _location = _lnkdata;\
494         _lnkdata  = lnk[_location];\
495       } while (_entry > _lnkdata);\
496       /* insertion location is found, add entry into lnk */\
497       lnk[_location]  = _entry;\
498       lnk[_entry]     = _lnkdata;\
499       lnklvl[_entry] = _incrlev;\
500       nlnk++;\
501       _lnkdata = _entry; /* next search starts from here if next_entry > _entry */\
502     } else { /* existing entry: update lnklvl */\
503       if (lnklvl[_entry] > _incrlev) lnklvl[_entry] = _incrlev;\
504     }\
505   }\
506 }
507 
508 /*
509   Add a SORTED index set into a sorted linked list
510   Input Parameters:
511     nidx      - number of input indices
512     idx   - sorted interger array used for storing column indices
513     level     - level of fill, e.g., ICC(level)
514     idxlvl - level of idx
515     idx_start - starting index of the list
516     lnk       - linked list(an integer array) that is created
517     lnklvl    - levels of lnk
518     bt        - PetscBT (bitarray), bt[idx]=true marks idx is in lnk
519   output Parameters:
520     nlnk      - number of newly added idx
521     lnk       - the sorted(increasing order) linked list containing new and non-redundate entries from idx
522     lnklvl    - levels of lnk
523     bt        - updated PetscBT (bitarray)
524 */
525 #define PetscIncompleteLLAddSorted(nidx,idx,level,idxlvl,idx_start,nlnk,lnk,lnklvl,bt) 0;\
526 {\
527   PetscInt _k,_entry,_location,_lnkdata,_incrlev;\
528   nlnk = 0;\
529   _lnkdata = idx_start;\
530   for (_k=0; _k<nidx; _k++){\
531     _incrlev = idxlvl[_k] + 1;\
532     if (_incrlev > level) continue;\
533     _entry = idx[_k];\
534     if (!PetscBTLookupSet(bt,_entry)){  /* new entry */\
535       /* search for insertion location */\
536       do {\
537         _location = _lnkdata;\
538         _lnkdata  = lnk[_location];\
539       } while (_entry > _lnkdata);\
540       /* insertion location is found, add entry into lnk */\
541       lnk[_location] = _entry;\
542       lnk[_entry]    = _lnkdata;\
543       lnklvl[_entry] = _incrlev;\
544       nlnk++;\
545       _lnkdata = _entry; /* next search starts from here */\
546     } else { /* existing entry: update lnklvl */\
547       if (lnklvl[_entry] > _incrlev) lnklvl[_entry] = _incrlev;\
548     }\
549   }\
550 }
551 
552 /*
553   Add a SORTED index set into a sorted linked list for ICC
554   Input Parameters:
555     nidx      - number of input indices
556     idx       - sorted interger array used for storing column indices
557     level     - level of fill, e.g., ICC(level)
558     idxlvl    - level of idx
559     idx_start - starting index of the list
560     lnk       - linked list(an integer array) that is created
561     lnklvl    - levels of lnk
562     bt        - PetscBT (bitarray), bt[idx]=true marks idx is in lnk
563     idxlvl_prow - idxlvl[prow], where prow is the row number of the idx
564   output Parameters:
565     nlnk   - number of newly added indices
566     lnk    - the sorted(increasing order) linked list containing new and non-redundate entries from idx
567     lnklvl - levels of lnk
568     bt     - updated PetscBT (bitarray)
569   Note: the level of U(i,j) is set as lvl(i,j) = min{ lvl(i,j), lvl(prow,i)+lvl(prow,j)+1)
570         where idx = non-zero columns of U(prow,prow+1:n-1), prow<i
571 */
572 #define PetscICCLLAddSorted(nidx,idx,level,idxlvl,idx_start,nlnk,lnk,lnklvl,bt,idxlvl_prow) 0;\
573 {\
574   PetscInt _k,_entry,_location,_lnkdata,_incrlev;\
575   nlnk = 0;\
576   _lnkdata = idx_start;\
577   for (_k=0; _k<nidx; _k++){\
578     _incrlev = idxlvl[_k] + idxlvl_prow + 1;\
579     if (_incrlev > level) continue;\
580     _entry = idx[_k];\
581     if (!PetscBTLookupSet(bt,_entry)){  /* new entry */\
582       /* search for insertion location */\
583       do {\
584         _location = _lnkdata;\
585         _lnkdata  = lnk[_location];\
586       } while (_entry > _lnkdata);\
587       /* insertion location is found, add entry into lnk */\
588       lnk[_location] = _entry;\
589       lnk[_entry]    = _lnkdata;\
590       lnklvl[_entry] = _incrlev;\
591       nlnk++;\
592       _lnkdata = _entry; /* next search starts from here */\
593     } else { /* existing entry: update lnklvl */\
594       if (lnklvl[_entry] > _incrlev) lnklvl[_entry] = _incrlev;\
595     }\
596   }\
597 }
598 
599 /*
600   Copy data on the list into an array, then initialize the list
601   Input Parameters:
602     idx_start - starting index of the list
603     lnk_max   - max value of lnk indicating the end of the list
604     nlnk      - number of data on the list to be copied
605     lnk       - linked list
606     lnklvl    - level of lnk
607     bt        - PetscBT (bitarray), bt[idx]=true marks idx is in lnk
608   output Parameters:
609     indices - array that contains the copied data
610     lnk     - linked list that is cleaned and initialize
611     lnklvl  - level of lnk that is reinitialized
612     bt      - PetscBT (bitarray) with all bits set to false
613 */
614 #define PetscIncompleteLLClean(idx_start,lnk_max,nlnk,lnk,lnklvl,indices,indiceslvl,bt) 0;\
615 {\
616   PetscInt _j,_idx=idx_start;\
617   for (_j=0; _j<nlnk; _j++){\
618     _idx = lnk[_idx];\
619     *(indices+_j) = _idx;\
620     *(indiceslvl+_j) = lnklvl[_idx];\
621     lnklvl[_idx] = -1;\
622     ierr = PetscBTClear(bt,_idx);CHKERRQ(ierr);\
623   }\
624   lnk[idx_start] = lnk_max;\
625 }
626 /*
627   Free memories used by the list
628 */
629 #define PetscIncompleteLLDestroy(lnk,bt) \
630   (PetscFree(lnk) || PetscBTDestroy(bt) || (0))
631 
632 PETSC_EXTERN_CXX_END
633 #endif /* __PETSCSYS_H */
634