17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay This file contains routines for sorting integers. Values are sorted in place. 459e16d97SJunchao Zhang One can use src/sys/examples/tests/ex52.c for benchmarking. 5e5c89e4eSSatish Balay */ 6af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 7e5c89e4eSSatish Balay 8a8582168SJed Brown #define MEDIAN3(v,a,b,c) \ 9a8582168SJed Brown (v[a]<v[b] \ 10a8582168SJed Brown ? (v[b]<v[c] \ 1159e16d97SJunchao Zhang ? (b) \ 1259e16d97SJunchao Zhang : (v[a]<v[c] ? (c) : (a))) \ 13a8582168SJed Brown : (v[c]<v[b] \ 1459e16d97SJunchao Zhang ? (b) \ 1559e16d97SJunchao Zhang : (v[a]<v[c] ? (a) : (c)))) 16a8582168SJed Brown 17a8582168SJed Brown #define MEDIAN(v,right) MEDIAN3(v,right/4,right/2,right/4*3) 18ef8e3583SJed Brown 1959e16d97SJunchao Zhang /* Swap one, two or three pairs. Each pair can have its own type */ 2059e16d97SJunchao Zhang #define SWAP1(a,b,t1) do {t1=a;a=b;b=t1;} while(0) 2159e16d97SJunchao Zhang #define SWAP2(a,b,c,d,t1,t2) do {t1=a;a=b;b=t1; t2=c;c=d;d=t2;} while(0) 2259e16d97SJunchao Zhang #define SWAP3(a,b,c,d,e,f,t1,t2,t3) do {t1=a;a=b;b=t1; t2=c;c=d;d=t2; t3=e;e=f;f=t3;} while(0) 2359e16d97SJunchao Zhang 2459e16d97SJunchao Zhang /* Swap a & b, *c & *d. c, d, t2 are pointers to a type of size <siz> */ 2559e16d97SJunchao Zhang #define SWAP2Data(a,b,c,d,t1,t2,siz) \ 2659e16d97SJunchao Zhang do { \ 2759e16d97SJunchao Zhang PetscErrorCode ierr; \ 2859e16d97SJunchao Zhang t1=a; a=b; b=t1; \ 2959e16d97SJunchao Zhang ierr = PetscMemcpy(t2,c,siz);CHKERRQ(ierr); \ 3059e16d97SJunchao Zhang ierr = PetscMemcpy(c,d,siz);CHKERRQ(ierr); \ 3159e16d97SJunchao Zhang ierr = PetscMemcpy(d,t2,siz);CHKERRQ(ierr); \ 3259e16d97SJunchao Zhang } while(0) 33e5c89e4eSSatish Balay 34e5c89e4eSSatish Balay /* 3559e16d97SJunchao Zhang Partition X[lo,hi] into two parts: X[lo,l) <= pivot; X[r,hi] > pivot 36e5c89e4eSSatish Balay 3759e16d97SJunchao Zhang Input Parameters: 3859e16d97SJunchao Zhang + X - array to partition 3959e16d97SJunchao Zhang . pivot - a pivot of X[] 4059e16d97SJunchao Zhang . t1 - temp variable for X 4159e16d97SJunchao Zhang - lo,hi - lower and upper bound of the array 4259e16d97SJunchao Zhang 4359e16d97SJunchao Zhang Output Parameters: 4459e16d97SJunchao Zhang + l,r - of type PetscInt 4559e16d97SJunchao Zhang 4659e16d97SJunchao Zhang Notes: 4759e16d97SJunchao Zhang The TwoWayPartition2/3 variants also partition other arrays along with X. 4859e16d97SJunchao Zhang These arrays can have different types, so they provide their own temp t2,t3 4959e16d97SJunchao Zhang */ 5059e16d97SJunchao Zhang #define TwoWayPartition1(X,pivot,t1,lo,hi,l,r) \ 5159e16d97SJunchao Zhang do { \ 5259e16d97SJunchao Zhang l = lo; \ 5359e16d97SJunchao Zhang r = hi; \ 5459e16d97SJunchao Zhang while(1) { \ 5559e16d97SJunchao Zhang while (X[l] < pivot) l++; \ 5659e16d97SJunchao Zhang while (X[r] > pivot) r--; \ 5759e16d97SJunchao Zhang if (l >= r) {r++; break;} \ 5859e16d97SJunchao Zhang SWAP1(X[l],X[r],t1); \ 5959e16d97SJunchao Zhang l++; \ 6059e16d97SJunchao Zhang r--; \ 6159e16d97SJunchao Zhang } \ 6259e16d97SJunchao Zhang } while(0) 6359e16d97SJunchao Zhang 6459e16d97SJunchao Zhang #define TwoWayPartition2(X,Y,pivot,t1,t2,lo,hi,l,r) \ 6559e16d97SJunchao Zhang do { \ 6659e16d97SJunchao Zhang l = lo; \ 6759e16d97SJunchao Zhang r = hi; \ 6859e16d97SJunchao Zhang while(1) { \ 6959e16d97SJunchao Zhang while (X[l] < pivot) l++; \ 7059e16d97SJunchao Zhang while (X[r] > pivot) r--; \ 7159e16d97SJunchao Zhang if (l >= r) {r++; break;} \ 7259e16d97SJunchao Zhang SWAP2(X[l],X[r],Y[l],Y[r],t1,t2); \ 7359e16d97SJunchao Zhang l++; \ 7459e16d97SJunchao Zhang r--; \ 7559e16d97SJunchao Zhang } \ 7659e16d97SJunchao Zhang } while(0) 7759e16d97SJunchao Zhang 7859e16d97SJunchao Zhang #define TwoWayPartition3(X,Y,Z,pivot,t1,t2,t3,lo,hi,l,r) \ 7959e16d97SJunchao Zhang do { \ 8059e16d97SJunchao Zhang l = lo; \ 8159e16d97SJunchao Zhang r = hi; \ 8259e16d97SJunchao Zhang while(1) { \ 8359e16d97SJunchao Zhang while (X[l] < pivot) l++; \ 8459e16d97SJunchao Zhang while (X[r] > pivot) r--; \ 8559e16d97SJunchao Zhang if (l >= r) {r++; break;} \ 8659e16d97SJunchao Zhang SWAP3(X[l],X[r],Y[l],Y[r],Z[l],Z[r],t1,t2,t3); \ 8759e16d97SJunchao Zhang l++; \ 8859e16d97SJunchao Zhang r--; \ 8959e16d97SJunchao Zhang } \ 9059e16d97SJunchao Zhang } while(0) 9159e16d97SJunchao Zhang 9259e16d97SJunchao Zhang /* Templates for similar functions used below */ 9359e16d97SJunchao Zhang #define QuickSort1(FuncName,X,n,pivot,t1,ierr) \ 9459e16d97SJunchao Zhang do { \ 9559e16d97SJunchao Zhang PetscInt i,j,p,l,r,hi=n-1; \ 9659e16d97SJunchao Zhang if (n < 8) { \ 9759e16d97SJunchao Zhang for (i=0; i<n; i++) { \ 9859e16d97SJunchao Zhang pivot = X[i]; \ 9959e16d97SJunchao Zhang for (j=i+1; j<n; j++) { \ 10059e16d97SJunchao Zhang if (pivot > X[j]) { \ 10159e16d97SJunchao Zhang SWAP1(X[i],X[j],t1); \ 10259e16d97SJunchao Zhang pivot = X[i]; \ 10359e16d97SJunchao Zhang } \ 10459e16d97SJunchao Zhang } \ 10559e16d97SJunchao Zhang } \ 10659e16d97SJunchao Zhang } else { \ 10759e16d97SJunchao Zhang p = MEDIAN(X,hi); \ 10859e16d97SJunchao Zhang pivot = X[p]; \ 10959e16d97SJunchao Zhang TwoWayPartition1(X,pivot,t1,0,hi,l,r); \ 11059e16d97SJunchao Zhang ierr = FuncName(l,X);CHKERRQ(ierr); \ 11159e16d97SJunchao Zhang ierr = FuncName(hi-r+1,X+r);CHKERRQ(ierr); \ 11259e16d97SJunchao Zhang } \ 11359e16d97SJunchao Zhang } while(0) 11459e16d97SJunchao Zhang 11559e16d97SJunchao Zhang #define QuickSort2(FuncName,X,Y,n,pivot,t1,t2,ierr) \ 11659e16d97SJunchao Zhang do { \ 11759e16d97SJunchao Zhang PetscInt i,j,p,l,r,hi=n-1; \ 11859e16d97SJunchao Zhang if (n < 8) { \ 11959e16d97SJunchao Zhang for (i=0; i<n; i++) { \ 12059e16d97SJunchao Zhang pivot = X[i]; \ 12159e16d97SJunchao Zhang for (j=i+1; j<n; j++) { \ 12259e16d97SJunchao Zhang if (pivot > X[j]) { \ 12359e16d97SJunchao Zhang SWAP2(X[i],X[j],Y[i],Y[j],t1,t2); \ 12459e16d97SJunchao Zhang pivot = X[i]; \ 12559e16d97SJunchao Zhang } \ 12659e16d97SJunchao Zhang } \ 12759e16d97SJunchao Zhang } \ 12859e16d97SJunchao Zhang } else { \ 12959e16d97SJunchao Zhang p = MEDIAN(X,hi); \ 13059e16d97SJunchao Zhang pivot = X[p]; \ 13159e16d97SJunchao Zhang TwoWayPartition2(X,Y,pivot,t1,t2,0,hi,l,r); \ 13259e16d97SJunchao Zhang ierr = FuncName(l,X,Y);CHKERRQ(ierr); \ 13359e16d97SJunchao Zhang ierr = FuncName(hi-r+1,X+r,Y+r);CHKERRQ(ierr); \ 13459e16d97SJunchao Zhang } \ 13559e16d97SJunchao Zhang } while(0) 13659e16d97SJunchao Zhang 13759e16d97SJunchao Zhang #define QuickSort3(FuncName,X,Y,Z,n,pivot,t1,t2,t3,ierr) \ 13859e16d97SJunchao Zhang do { \ 13959e16d97SJunchao Zhang PetscInt i,j,p,l,r,hi=n-1; \ 14059e16d97SJunchao Zhang if (n < 8) { \ 14159e16d97SJunchao Zhang for (i=0; i<n; i++) { \ 14259e16d97SJunchao Zhang pivot = X[i]; \ 14359e16d97SJunchao Zhang for (j=i+1; j<n; j++) { \ 14459e16d97SJunchao Zhang if (pivot > X[j]) { \ 14559e16d97SJunchao Zhang SWAP3(X[i],X[j],Y[i],Y[j],Z[i],Z[j],t1,t2,t3); \ 14659e16d97SJunchao Zhang pivot = X[i]; \ 14759e16d97SJunchao Zhang } \ 14859e16d97SJunchao Zhang } \ 14959e16d97SJunchao Zhang } \ 15059e16d97SJunchao Zhang } else { \ 15159e16d97SJunchao Zhang p = MEDIAN(X,hi); \ 15259e16d97SJunchao Zhang pivot = X[p]; \ 15359e16d97SJunchao Zhang TwoWayPartition3(X,Y,Z,pivot,t1,t2,t3,0,hi,l,r); \ 15459e16d97SJunchao Zhang ierr = FuncName(l,X,Y,Z);CHKERRQ(ierr); \ 15559e16d97SJunchao Zhang ierr = FuncName(hi-r+1,X+r,Y+r,Z+r);CHKERRQ(ierr); \ 15659e16d97SJunchao Zhang } \ 15759e16d97SJunchao Zhang } while(0) 158e5c89e4eSSatish Balay 159e5c89e4eSSatish Balay /*@ 160e5c89e4eSSatish Balay PetscSortInt - Sorts an array of integers in place in increasing order. 161e5c89e4eSSatish Balay 162e5c89e4eSSatish Balay Not Collective 163e5c89e4eSSatish Balay 164e5c89e4eSSatish Balay Input Parameters: 165e5c89e4eSSatish Balay + n - number of values 16659e16d97SJunchao Zhang - X - array of integers 167e5c89e4eSSatish Balay 168e5c89e4eSSatish Balay Level: intermediate 169e5c89e4eSSatish Balay 170e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntWithPermutation() 171e5c89e4eSSatish Balay @*/ 172*b4f531b9SJunchao Zhang PetscErrorCode PetscSortInt(PetscInt n,PetscInt X[]) 173e5c89e4eSSatish Balay { 17459e16d97SJunchao Zhang PetscErrorCode ierr; 17559e16d97SJunchao Zhang PetscInt pivot,t1; 176e5c89e4eSSatish Balay 177e5c89e4eSSatish Balay PetscFunctionBegin; 17859e16d97SJunchao Zhang QuickSort1(PetscSortInt,X,n,pivot,t1,ierr); 179e5c89e4eSSatish Balay PetscFunctionReturn(0); 180e5c89e4eSSatish Balay } 181e5c89e4eSSatish Balay 1821db36a52SBarry Smith /*@ 18322ab5688SLisandro Dalcin PetscSortedRemoveDupsInt - Removes all duplicate entries of a sorted input array 18422ab5688SLisandro Dalcin 18522ab5688SLisandro Dalcin Not Collective 18622ab5688SLisandro Dalcin 18722ab5688SLisandro Dalcin Input Parameters: 18822ab5688SLisandro Dalcin + n - number of values 18959e16d97SJunchao Zhang - X - sorted array of integers 19022ab5688SLisandro Dalcin 19122ab5688SLisandro Dalcin Output Parameter: 19222ab5688SLisandro Dalcin . n - number of non-redundant values 19322ab5688SLisandro Dalcin 19422ab5688SLisandro Dalcin Level: intermediate 19522ab5688SLisandro Dalcin 19622ab5688SLisandro Dalcin .seealso: PetscSortInt() 19722ab5688SLisandro Dalcin @*/ 19859e16d97SJunchao Zhang PetscErrorCode PetscSortedRemoveDupsInt(PetscInt *n,PetscInt X[]) 19922ab5688SLisandro Dalcin { 20022ab5688SLisandro Dalcin PetscInt i,s = 0,N = *n, b = 0; 20122ab5688SLisandro Dalcin 20222ab5688SLisandro Dalcin PetscFunctionBegin; 20322ab5688SLisandro Dalcin for (i=0; i<N-1; i++) { 20459e16d97SJunchao Zhang if (PetscUnlikely(X[b+s+1] < X[b])) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Input array is not sorted"); 20559e16d97SJunchao Zhang if (X[b+s+1] != X[b]) { 20659e16d97SJunchao Zhang X[b+1] = X[b+s+1]; b++; 20722ab5688SLisandro Dalcin } else s++; 20822ab5688SLisandro Dalcin } 20922ab5688SLisandro Dalcin *n = N - s; 21022ab5688SLisandro Dalcin PetscFunctionReturn(0); 21122ab5688SLisandro Dalcin } 21222ab5688SLisandro Dalcin 21322ab5688SLisandro Dalcin /*@ 2141db36a52SBarry Smith PetscSortRemoveDupsInt - Sorts an array of integers in place in increasing order removes all duplicate entries 2151db36a52SBarry Smith 2161db36a52SBarry Smith Not Collective 2171db36a52SBarry Smith 2181db36a52SBarry Smith Input Parameters: 2191db36a52SBarry Smith + n - number of values 22059e16d97SJunchao Zhang - X - array of integers 2211db36a52SBarry Smith 2221db36a52SBarry Smith Output Parameter: 2231db36a52SBarry Smith . n - number of non-redundant values 2241db36a52SBarry Smith 2251db36a52SBarry Smith Level: intermediate 2261db36a52SBarry Smith 22722ab5688SLisandro Dalcin .seealso: PetscSortReal(), PetscSortIntWithPermutation(), PetscSortInt(), PetscSortedRemoveDupsInt() 2281db36a52SBarry Smith @*/ 22959e16d97SJunchao Zhang PetscErrorCode PetscSortRemoveDupsInt(PetscInt *n,PetscInt X[]) 2301db36a52SBarry Smith { 2311db36a52SBarry Smith PetscErrorCode ierr; 2321db36a52SBarry Smith 2331db36a52SBarry Smith PetscFunctionBegin; 23459e16d97SJunchao Zhang ierr = PetscSortInt(*n,X);CHKERRQ(ierr); 23559e16d97SJunchao Zhang ierr = PetscSortedRemoveDupsInt(n,X);CHKERRQ(ierr); 2361db36a52SBarry Smith PetscFunctionReturn(0); 2371db36a52SBarry Smith } 2381db36a52SBarry Smith 23960e03357SMatthew G Knepley /*@ 240d9f1162dSJed Brown PetscFindInt - Finds integer in a sorted array of integers 24160e03357SMatthew G Knepley 24260e03357SMatthew G Knepley Not Collective 24360e03357SMatthew G Knepley 24460e03357SMatthew G Knepley Input Parameters: 24560e03357SMatthew G Knepley + key - the integer to locate 246d9f1162dSJed Brown . n - number of values in the array 24759e16d97SJunchao Zhang - X - array of integers 24860e03357SMatthew G Knepley 24960e03357SMatthew G Knepley Output Parameter: 250d9f1162dSJed Brown . loc - the location if found, otherwise -(slot+1) where slot is the place the value would go 25160e03357SMatthew G Knepley 25260e03357SMatthew G Knepley Level: intermediate 25360e03357SMatthew G Knepley 25460e03357SMatthew G Knepley .seealso: PetscSortInt(), PetscSortIntWithArray(), PetscSortRemoveDupsInt() 25560e03357SMatthew G Knepley @*/ 25659e16d97SJunchao Zhang PetscErrorCode PetscFindInt(PetscInt key, PetscInt n, const PetscInt X[], PetscInt *loc) 25760e03357SMatthew G Knepley { 258d9f1162dSJed Brown PetscInt lo = 0,hi = n; 25960e03357SMatthew G Knepley 26060e03357SMatthew G Knepley PetscFunctionBegin; 26160e03357SMatthew G Knepley PetscValidPointer(loc,4); 26298781d82SMatthew G Knepley if (!n) {*loc = -1; PetscFunctionReturn(0);} 26359e16d97SJunchao Zhang PetscValidPointer(X,3); 264d9f1162dSJed Brown while (hi - lo > 1) { 265d9f1162dSJed Brown PetscInt mid = lo + (hi - lo)/2; 26659e16d97SJunchao Zhang if (key < X[mid]) hi = mid; 267d9f1162dSJed Brown else lo = mid; 26860e03357SMatthew G Knepley } 26959e16d97SJunchao Zhang *loc = key == X[lo] ? lo : -(lo + (key > X[lo]) + 1); 27060e03357SMatthew G Knepley PetscFunctionReturn(0); 27160e03357SMatthew G Knepley } 27260e03357SMatthew G Knepley 273d2aeb606SJed Brown /*@ 274d2aeb606SJed Brown PetscFindMPIInt - Finds MPI integer in a sorted array of integers 275d2aeb606SJed Brown 276d2aeb606SJed Brown Not Collective 277d2aeb606SJed Brown 278d2aeb606SJed Brown Input Parameters: 279d2aeb606SJed Brown + key - the integer to locate 280d2aeb606SJed Brown . n - number of values in the array 28159e16d97SJunchao Zhang - X - array of integers 282d2aeb606SJed Brown 283d2aeb606SJed Brown Output Parameter: 284d2aeb606SJed Brown . loc - the location if found, otherwise -(slot+1) where slot is the place the value would go 285d2aeb606SJed Brown 286d2aeb606SJed Brown Level: intermediate 287d2aeb606SJed Brown 288d2aeb606SJed Brown .seealso: PetscSortInt(), PetscSortIntWithArray(), PetscSortRemoveDupsInt() 289d2aeb606SJed Brown @*/ 29059e16d97SJunchao Zhang PetscErrorCode PetscFindMPIInt(PetscMPIInt key, PetscInt n, const PetscMPIInt X[], PetscInt *loc) 291d2aeb606SJed Brown { 292d2aeb606SJed Brown PetscInt lo = 0,hi = n; 293d2aeb606SJed Brown 294d2aeb606SJed Brown PetscFunctionBegin; 295d2aeb606SJed Brown PetscValidPointer(loc,4); 296d2aeb606SJed Brown if (!n) {*loc = -1; PetscFunctionReturn(0);} 29759e16d97SJunchao Zhang PetscValidPointer(X,3); 298d2aeb606SJed Brown while (hi - lo > 1) { 299d2aeb606SJed Brown PetscInt mid = lo + (hi - lo)/2; 30059e16d97SJunchao Zhang if (key < X[mid]) hi = mid; 301d2aeb606SJed Brown else lo = mid; 302d2aeb606SJed Brown } 30359e16d97SJunchao Zhang *loc = key == X[lo] ? lo : -(lo + (key > X[lo]) + 1); 304e5c89e4eSSatish Balay PetscFunctionReturn(0); 305e5c89e4eSSatish Balay } 306e5c89e4eSSatish Balay 307e5c89e4eSSatish Balay /*@ 308e5c89e4eSSatish Balay PetscSortIntWithArray - Sorts an array of integers in place in increasing order; 309e5c89e4eSSatish Balay changes a second array to match the sorted first array. 310e5c89e4eSSatish Balay 311e5c89e4eSSatish Balay Not Collective 312e5c89e4eSSatish Balay 313e5c89e4eSSatish Balay Input Parameters: 314e5c89e4eSSatish Balay + n - number of values 31559e16d97SJunchao Zhang . X - array of integers 31659e16d97SJunchao Zhang - Y - second array of integers 317e5c89e4eSSatish Balay 318e5c89e4eSSatish Balay Level: intermediate 319e5c89e4eSSatish Balay 320e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 321e5c89e4eSSatish Balay @*/ 322*b4f531b9SJunchao Zhang PetscErrorCode PetscSortIntWithArray(PetscInt n,PetscInt X[],PetscInt Y[]) 323e5c89e4eSSatish Balay { 324e5c89e4eSSatish Balay PetscErrorCode ierr; 32559e16d97SJunchao Zhang PetscInt pivot,t1,t2; 326e5c89e4eSSatish Balay 327e5c89e4eSSatish Balay PetscFunctionBegin; 32859e16d97SJunchao Zhang QuickSort2(PetscSortIntWithArray,X,Y,n,pivot,t1,t2,ierr); 329c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 330c1f0200aSDmitry Karpeev } 331c1f0200aSDmitry Karpeev 332c1f0200aSDmitry Karpeev /*@ 333c1f0200aSDmitry Karpeev PetscSortIntWithArrayPair - Sorts an array of integers in place in increasing order; 334c1f0200aSDmitry Karpeev changes a pair of integer arrays to match the sorted first array. 335c1f0200aSDmitry Karpeev 336c1f0200aSDmitry Karpeev Not Collective 337c1f0200aSDmitry Karpeev 338c1f0200aSDmitry Karpeev Input Parameters: 339c1f0200aSDmitry Karpeev + n - number of values 34059e16d97SJunchao Zhang . X - array of integers 34159e16d97SJunchao Zhang . Y - second array of integers (first array of the pair) 34259e16d97SJunchao Zhang - Z - third array of integers (second array of the pair) 343c1f0200aSDmitry Karpeev 344c1f0200aSDmitry Karpeev Level: intermediate 345c1f0200aSDmitry Karpeev 346c1f0200aSDmitry Karpeev .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortIntWithArray() 347c1f0200aSDmitry Karpeev @*/ 348*b4f531b9SJunchao Zhang PetscErrorCode PetscSortIntWithArrayPair(PetscInt n,PetscInt X[],PetscInt Y[],PetscInt Z[]) 349c1f0200aSDmitry Karpeev { 350c1f0200aSDmitry Karpeev PetscErrorCode ierr; 35159e16d97SJunchao Zhang PetscInt pivot,t1,t2,t3; 352c1f0200aSDmitry Karpeev 353c1f0200aSDmitry Karpeev PetscFunctionBegin; 35459e16d97SJunchao Zhang QuickSort3(PetscSortIntWithArrayPair,X,Y,Z,n,pivot,t1,t2,t3,ierr); 355c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 356c1f0200aSDmitry Karpeev } 357c1f0200aSDmitry Karpeev 35817d7d925SStefano Zampini /*@ 35917d7d925SStefano Zampini PetscSortMPIInt - Sorts an array of MPI integers in place in increasing order. 36017d7d925SStefano Zampini 36117d7d925SStefano Zampini Not Collective 36217d7d925SStefano Zampini 36317d7d925SStefano Zampini Input Parameters: 36417d7d925SStefano Zampini + n - number of values 36559e16d97SJunchao Zhang - X - array of integers 36617d7d925SStefano Zampini 36717d7d925SStefano Zampini Level: intermediate 36817d7d925SStefano Zampini 36917d7d925SStefano Zampini .seealso: PetscSortReal(), PetscSortIntWithPermutation() 37017d7d925SStefano Zampini @*/ 371*b4f531b9SJunchao Zhang PetscErrorCode PetscSortMPIInt(PetscInt n,PetscMPIInt X[]) 37217d7d925SStefano Zampini { 37359e16d97SJunchao Zhang PetscErrorCode ierr; 37459e16d97SJunchao Zhang PetscMPIInt pivot,t1; 37517d7d925SStefano Zampini 37617d7d925SStefano Zampini PetscFunctionBegin; 37759e16d97SJunchao Zhang QuickSort1(PetscSortMPIInt,X,n,pivot,t1,ierr); 37817d7d925SStefano Zampini PetscFunctionReturn(0); 37917d7d925SStefano Zampini } 38017d7d925SStefano Zampini 38117d7d925SStefano Zampini /*@ 38217d7d925SStefano Zampini PetscSortRemoveDupsMPIInt - Sorts an array of MPI integers in place in increasing order removes all duplicate entries 38317d7d925SStefano Zampini 38417d7d925SStefano Zampini Not Collective 38517d7d925SStefano Zampini 38617d7d925SStefano Zampini Input Parameters: 38717d7d925SStefano Zampini + n - number of values 38859e16d97SJunchao Zhang - X - array of integers 38917d7d925SStefano Zampini 39017d7d925SStefano Zampini Output Parameter: 39117d7d925SStefano Zampini . n - number of non-redundant values 39217d7d925SStefano Zampini 39317d7d925SStefano Zampini Level: intermediate 39417d7d925SStefano Zampini 39517d7d925SStefano Zampini .seealso: PetscSortReal(), PetscSortIntWithPermutation(), PetscSortInt() 39617d7d925SStefano Zampini @*/ 39759e16d97SJunchao Zhang PetscErrorCode PetscSortRemoveDupsMPIInt(PetscInt *n,PetscMPIInt X[]) 39817d7d925SStefano Zampini { 39917d7d925SStefano Zampini PetscErrorCode ierr; 40017d7d925SStefano Zampini PetscInt i,s = 0,N = *n, b = 0; 40117d7d925SStefano Zampini 40217d7d925SStefano Zampini PetscFunctionBegin; 40359e16d97SJunchao Zhang ierr = PetscSortMPIInt(N,X);CHKERRQ(ierr); 40417d7d925SStefano Zampini for (i=0; i<N-1; i++) { 40559e16d97SJunchao Zhang if (X[b+s+1] != X[b]) { 40659e16d97SJunchao Zhang X[b+1] = X[b+s+1]; b++; 407a297a907SKarl Rupp } else s++; 40817d7d925SStefano Zampini } 40917d7d925SStefano Zampini *n = N - s; 41017d7d925SStefano Zampini PetscFunctionReturn(0); 41117d7d925SStefano Zampini } 412c1f0200aSDmitry Karpeev 4134d615ea0SBarry Smith /*@ 4144d615ea0SBarry Smith PetscSortMPIIntWithArray - Sorts an array of integers in place in increasing order; 4154d615ea0SBarry Smith changes a second array to match the sorted first array. 4164d615ea0SBarry Smith 4174d615ea0SBarry Smith Not Collective 4184d615ea0SBarry Smith 4194d615ea0SBarry Smith Input Parameters: 4204d615ea0SBarry Smith + n - number of values 42159e16d97SJunchao Zhang . X - array of integers 42259e16d97SJunchao Zhang - Y - second array of integers 4234d615ea0SBarry Smith 4244d615ea0SBarry Smith Level: intermediate 4254d615ea0SBarry Smith 4264d615ea0SBarry Smith .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 4274d615ea0SBarry Smith @*/ 428*b4f531b9SJunchao Zhang PetscErrorCode PetscSortMPIIntWithArray(PetscMPIInt n,PetscMPIInt X[],PetscMPIInt Y[]) 4294d615ea0SBarry Smith { 4304d615ea0SBarry Smith PetscErrorCode ierr; 43159e16d97SJunchao Zhang PetscMPIInt pivot,t1,t2; 4324d615ea0SBarry Smith 4334d615ea0SBarry Smith PetscFunctionBegin; 43459e16d97SJunchao Zhang QuickSort2(PetscSortMPIIntWithArray,X,Y,n,pivot,t1,t2,ierr); 4355569a785SJunchao Zhang PetscFunctionReturn(0); 4365569a785SJunchao Zhang } 4375569a785SJunchao Zhang 4385569a785SJunchao Zhang /*@ 4395569a785SJunchao Zhang PetscSortMPIIntWithIntArray - Sorts an array of MPI integers in place in increasing order; 4405569a785SJunchao Zhang changes a second array of Petsc intergers to match the sorted first array. 4415569a785SJunchao Zhang 4425569a785SJunchao Zhang Not Collective 4435569a785SJunchao Zhang 4445569a785SJunchao Zhang Input Parameters: 4455569a785SJunchao Zhang + n - number of values 44659e16d97SJunchao Zhang . X - array of MPI integers 44759e16d97SJunchao Zhang - Y - second array of Petsc integers 4485569a785SJunchao Zhang 4495569a785SJunchao Zhang Level: intermediate 4505569a785SJunchao Zhang 4515569a785SJunchao Zhang Notes: this routine is useful when one needs to sort MPI ranks with other integer arrays. 4525569a785SJunchao Zhang 4535569a785SJunchao Zhang .seealso: PetscSortMPIIntWithArray() 4545569a785SJunchao Zhang @*/ 455*b4f531b9SJunchao Zhang PetscErrorCode PetscSortMPIIntWithIntArray(PetscMPIInt n,PetscMPIInt X[],PetscInt Y[]) 4565569a785SJunchao Zhang { 4575569a785SJunchao Zhang PetscErrorCode ierr; 45859e16d97SJunchao Zhang PetscMPIInt pivot,t1; 4595569a785SJunchao Zhang PetscInt t2; 4605569a785SJunchao Zhang 4615569a785SJunchao Zhang PetscFunctionBegin; 46259e16d97SJunchao Zhang QuickSort2(PetscSortMPIIntWithIntArray,X,Y,n,pivot,t1,t2,ierr); 463e5c89e4eSSatish Balay PetscFunctionReturn(0); 464e5c89e4eSSatish Balay } 465e5c89e4eSSatish Balay 466e5c89e4eSSatish Balay /*@ 467e5c89e4eSSatish Balay PetscSortIntWithScalarArray - Sorts an array of integers in place in increasing order; 468e5c89e4eSSatish Balay changes a second SCALAR array to match the sorted first INTEGER array. 469e5c89e4eSSatish Balay 470e5c89e4eSSatish Balay Not Collective 471e5c89e4eSSatish Balay 472e5c89e4eSSatish Balay Input Parameters: 473e5c89e4eSSatish Balay + n - number of values 47459e16d97SJunchao Zhang . X - array of integers 47559e16d97SJunchao Zhang - Y - second array of scalars 476e5c89e4eSSatish Balay 477e5c89e4eSSatish Balay Level: intermediate 478e5c89e4eSSatish Balay 479e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 480e5c89e4eSSatish Balay @*/ 481*b4f531b9SJunchao Zhang PetscErrorCode PetscSortIntWithScalarArray(PetscInt n,PetscInt X[],PetscScalar Y[]) 482e5c89e4eSSatish Balay { 483e5c89e4eSSatish Balay PetscErrorCode ierr; 48459e16d97SJunchao Zhang PetscInt pivot,t1; 48559e16d97SJunchao Zhang PetscScalar t2; 486e5c89e4eSSatish Balay 487e5c89e4eSSatish Balay PetscFunctionBegin; 48859e16d97SJunchao Zhang QuickSort2(PetscSortIntWithScalarArray,X,Y,n,pivot,t1,t2,ierr); 48917df18f2SToby Isaac PetscFunctionReturn(0); 49017df18f2SToby Isaac } 49117df18f2SToby Isaac 4926c2863d0SBarry Smith /*@C 49317df18f2SToby Isaac PetscSortIntWithDataArray - Sorts an array of integers in place in increasing order; 49417df18f2SToby Isaac changes a second array to match the sorted first INTEGER array. Unlike other sort routines, the user must 49517df18f2SToby Isaac provide workspace (the size of an element in the data array) to use when sorting. 49617df18f2SToby Isaac 49717df18f2SToby Isaac Not Collective 49817df18f2SToby Isaac 49917df18f2SToby Isaac Input Parameters: 50017df18f2SToby Isaac + n - number of values 50159e16d97SJunchao Zhang . X - array of integers 50259e16d97SJunchao Zhang . Y - second array of data 50317df18f2SToby Isaac . size - sizeof elements in the data array in bytes 50459e16d97SJunchao Zhang - t2 - workspace of "size" bytes used when sorting 50517df18f2SToby Isaac 50617df18f2SToby Isaac Level: intermediate 50717df18f2SToby Isaac 50817df18f2SToby Isaac .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 50917df18f2SToby Isaac @*/ 510*b4f531b9SJunchao Zhang PetscErrorCode PetscSortIntWithDataArray(PetscInt n,PetscInt X[],void *Y,size_t size,void *t2) 51117df18f2SToby Isaac { 51217df18f2SToby Isaac PetscErrorCode ierr; 51359e16d97SJunchao Zhang char *YY = (char*)Y; 51459e16d97SJunchao Zhang PetscInt i,j,p,t1,pivot,hi=n-1,l,r; 51517df18f2SToby Isaac 51617df18f2SToby Isaac PetscFunctionBegin; 51717df18f2SToby Isaac if (n<8) { 51859e16d97SJunchao Zhang for (i=0; i<n; i++) { 51959e16d97SJunchao Zhang pivot = X[i]; 52059e16d97SJunchao Zhang for (j=i+1; j<n; j++) { 52159e16d97SJunchao Zhang if (pivot > X[j]) { 52259e16d97SJunchao Zhang SWAP2Data(X[i],X[j],YY+size*i,YY+size*j,t1,t2,size); 52359e16d97SJunchao Zhang pivot = X[i]; 52417df18f2SToby Isaac } 52517df18f2SToby Isaac } 52617df18f2SToby Isaac } 52717df18f2SToby Isaac } else { 52859e16d97SJunchao Zhang /* Two way partition */ 52959e16d97SJunchao Zhang p = MEDIAN(X,hi); 53059e16d97SJunchao Zhang pivot = X[p]; 53159e16d97SJunchao Zhang l = 0; 53259e16d97SJunchao Zhang r = hi; 53359e16d97SJunchao Zhang while(1) { 53459e16d97SJunchao Zhang while (X[l] < pivot) l++; 53559e16d97SJunchao Zhang while (X[r] > pivot) r--; 53659e16d97SJunchao Zhang if (l >= r) {r++; break;} 53759e16d97SJunchao Zhang SWAP2Data(X[l],X[r],YY+size*l,YY+size*r,t1,t2,size); 53859e16d97SJunchao Zhang l++; 53959e16d97SJunchao Zhang r--; 54059e16d97SJunchao Zhang } 54159e16d97SJunchao Zhang ierr = PetscSortIntWithDataArray(l,X,Y,size,t2);CHKERRQ(ierr); 54259e16d97SJunchao Zhang ierr = PetscSortIntWithDataArray(hi-r+1,X+r,YY+size*r,size,t2);CHKERRQ(ierr); 54317df18f2SToby Isaac } 54417df18f2SToby Isaac PetscFunctionReturn(0); 54517df18f2SToby Isaac } 54617df18f2SToby Isaac 54721e72a00SBarry Smith /*@ 54821e72a00SBarry Smith PetscMergeIntArray - Merges two SORTED integer arrays, removes duplicate elements. 54921e72a00SBarry Smith 55021e72a00SBarry Smith Not Collective 55121e72a00SBarry Smith 55221e72a00SBarry Smith Input Parameters: 55321e72a00SBarry Smith + an - number of values in the first array 55421e72a00SBarry Smith . aI - first sorted array of integers 55521e72a00SBarry Smith . bn - number of values in the second array 55621e72a00SBarry Smith - bI - second array of integers 55721e72a00SBarry Smith 55821e72a00SBarry Smith Output Parameters: 55921e72a00SBarry Smith + n - number of values in the merged array 5606c2863d0SBarry Smith - L - merged sorted array, this is allocated if an array is not provided 56121e72a00SBarry Smith 56221e72a00SBarry Smith Level: intermediate 56321e72a00SBarry Smith 56421e72a00SBarry Smith .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 56521e72a00SBarry Smith @*/ 5666c2863d0SBarry Smith PetscErrorCode PetscMergeIntArray(PetscInt an,const PetscInt aI[], PetscInt bn, const PetscInt bI[], PetscInt *n, PetscInt **L) 56721e72a00SBarry Smith { 56821e72a00SBarry Smith PetscErrorCode ierr; 56921e72a00SBarry Smith PetscInt *L_ = *L, ak, bk, k; 57021e72a00SBarry Smith 57121e72a00SBarry Smith if (!L_) { 57221e72a00SBarry Smith ierr = PetscMalloc1(an+bn, L);CHKERRQ(ierr); 57321e72a00SBarry Smith L_ = *L; 57421e72a00SBarry Smith } 57521e72a00SBarry Smith k = ak = bk = 0; 57621e72a00SBarry Smith while (ak < an && bk < bn) { 57721e72a00SBarry Smith if (aI[ak] == bI[bk]) { 57821e72a00SBarry Smith L_[k] = aI[ak]; 57921e72a00SBarry Smith ++ak; 58021e72a00SBarry Smith ++bk; 58121e72a00SBarry Smith ++k; 58221e72a00SBarry Smith } else if (aI[ak] < bI[bk]) { 58321e72a00SBarry Smith L_[k] = aI[ak]; 58421e72a00SBarry Smith ++ak; 58521e72a00SBarry Smith ++k; 58621e72a00SBarry Smith } else { 58721e72a00SBarry Smith L_[k] = bI[bk]; 58821e72a00SBarry Smith ++bk; 58921e72a00SBarry Smith ++k; 59021e72a00SBarry Smith } 59121e72a00SBarry Smith } 59221e72a00SBarry Smith if (ak < an) { 593580bdb30SBarry Smith ierr = PetscArraycpy(L_+k,aI+ak,an-ak);CHKERRQ(ierr); 59421e72a00SBarry Smith k += (an-ak); 59521e72a00SBarry Smith } 59621e72a00SBarry Smith if (bk < bn) { 597580bdb30SBarry Smith ierr = PetscArraycpy(L_+k,bI+bk,bn-bk);CHKERRQ(ierr); 59821e72a00SBarry Smith k += (bn-bk); 59921e72a00SBarry Smith } 60021e72a00SBarry Smith *n = k; 60121e72a00SBarry Smith PetscFunctionReturn(0); 60221e72a00SBarry Smith } 603b4301105SBarry Smith 604c1f0200aSDmitry Karpeev /*@ 60521e72a00SBarry Smith PetscMergeIntArrayPair - Merges two SORTED integer arrays that share NO common values along with an additional array of integers. 606c1f0200aSDmitry Karpeev The additional arrays are the same length as sorted arrays and are merged 607c1f0200aSDmitry Karpeev in the order determined by the merging of the sorted pair. 608c1f0200aSDmitry Karpeev 609c1f0200aSDmitry Karpeev Not Collective 610c1f0200aSDmitry Karpeev 611c1f0200aSDmitry Karpeev Input Parameters: 612c1f0200aSDmitry Karpeev + an - number of values in the first array 613c1f0200aSDmitry Karpeev . aI - first sorted array of integers 614c1f0200aSDmitry Karpeev . aJ - first additional array of integers 615c1f0200aSDmitry Karpeev . bn - number of values in the second array 616c1f0200aSDmitry Karpeev . bI - second array of integers 617c1f0200aSDmitry Karpeev - bJ - second additional of integers 618c1f0200aSDmitry Karpeev 619c1f0200aSDmitry Karpeev Output Parameters: 620c1f0200aSDmitry Karpeev + n - number of values in the merged array (== an + bn) 62114c49006SJed Brown . L - merged sorted array 622c1f0200aSDmitry Karpeev - J - merged additional array 623c1f0200aSDmitry Karpeev 62495452b02SPatrick Sanan Notes: 62595452b02SPatrick Sanan if L or J point to non-null arrays then this routine will assume they are of the approproate size and use them, otherwise this routine will allocate space for them 626c1f0200aSDmitry Karpeev Level: intermediate 627c1f0200aSDmitry Karpeev 628c1f0200aSDmitry Karpeev .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 629c1f0200aSDmitry Karpeev @*/ 6306c2863d0SBarry Smith PetscErrorCode PetscMergeIntArrayPair(PetscInt an,const PetscInt aI[], const PetscInt aJ[], PetscInt bn, const PetscInt bI[], const PetscInt bJ[], PetscInt *n, PetscInt **L, PetscInt **J) 631c1f0200aSDmitry Karpeev { 632c1f0200aSDmitry Karpeev PetscErrorCode ierr; 63370d8d27cSBarry Smith PetscInt n_, *L_, *J_, ak, bk, k; 634c1f0200aSDmitry Karpeev 63514c49006SJed Brown PetscFunctionBegin; 63670d8d27cSBarry Smith PetscValidIntPointer(L,8); 63770d8d27cSBarry Smith PetscValidIntPointer(J,9); 638c1f0200aSDmitry Karpeev n_ = an + bn; 639c1f0200aSDmitry Karpeev *n = n_; 64070d8d27cSBarry Smith if (!*L) { 641785e854fSJed Brown ierr = PetscMalloc1(n_, L);CHKERRQ(ierr); 64270d8d27cSBarry Smith } 643d7aa01a8SHong Zhang L_ = *L; 64470d8d27cSBarry Smith if (!*J) { 64570d8d27cSBarry Smith ierr = PetscMalloc1(n_, J);CHKERRQ(ierr); 646c1f0200aSDmitry Karpeev } 647c1f0200aSDmitry Karpeev J_ = *J; 648c1f0200aSDmitry Karpeev k = ak = bk = 0; 649c1f0200aSDmitry Karpeev while (ak < an && bk < bn) { 650c1f0200aSDmitry Karpeev if (aI[ak] <= bI[bk]) { 651d7aa01a8SHong Zhang L_[k] = aI[ak]; 652c1f0200aSDmitry Karpeev J_[k] = aJ[ak]; 653c1f0200aSDmitry Karpeev ++ak; 654c1f0200aSDmitry Karpeev ++k; 655a297a907SKarl Rupp } else { 656d7aa01a8SHong Zhang L_[k] = bI[bk]; 657c1f0200aSDmitry Karpeev J_[k] = bJ[bk]; 658c1f0200aSDmitry Karpeev ++bk; 659c1f0200aSDmitry Karpeev ++k; 660c1f0200aSDmitry Karpeev } 661c1f0200aSDmitry Karpeev } 662c1f0200aSDmitry Karpeev if (ak < an) { 663580bdb30SBarry Smith ierr = PetscArraycpy(L_+k,aI+ak,an-ak);CHKERRQ(ierr); 664580bdb30SBarry Smith ierr = PetscArraycpy(J_+k,aJ+ak,an-ak);CHKERRQ(ierr); 665c1f0200aSDmitry Karpeev k += (an-ak); 666c1f0200aSDmitry Karpeev } 667c1f0200aSDmitry Karpeev if (bk < bn) { 668580bdb30SBarry Smith ierr = PetscArraycpy(L_+k,bI+bk,bn-bk);CHKERRQ(ierr); 669580bdb30SBarry Smith ierr = PetscArraycpy(J_+k,bJ+bk,bn-bk);CHKERRQ(ierr); 670c1f0200aSDmitry Karpeev } 671c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 672c1f0200aSDmitry Karpeev } 673c1f0200aSDmitry Karpeev 674e498c390SJed Brown /*@ 675e498c390SJed Brown PetscMergeMPIIntArray - Merges two SORTED integer arrays. 676e498c390SJed Brown 677e498c390SJed Brown Not Collective 678e498c390SJed Brown 679e498c390SJed Brown Input Parameters: 680e498c390SJed Brown + an - number of values in the first array 681e498c390SJed Brown . aI - first sorted array of integers 682e498c390SJed Brown . bn - number of values in the second array 683e498c390SJed Brown - bI - second array of integers 684e498c390SJed Brown 685e498c390SJed Brown Output Parameters: 686e498c390SJed Brown + n - number of values in the merged array (<= an + bn) 687e498c390SJed Brown - L - merged sorted array, allocated if address of NULL pointer is passed 688e498c390SJed Brown 689e498c390SJed Brown Level: intermediate 690e498c390SJed Brown 691e498c390SJed Brown .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 692e498c390SJed Brown @*/ 693e498c390SJed Brown PetscErrorCode PetscMergeMPIIntArray(PetscInt an,const PetscMPIInt aI[],PetscInt bn,const PetscMPIInt bI[],PetscInt *n,PetscMPIInt **L) 694e498c390SJed Brown { 695e498c390SJed Brown PetscErrorCode ierr; 696e498c390SJed Brown PetscInt ai,bi,k; 697e498c390SJed Brown 698e498c390SJed Brown PetscFunctionBegin; 699e498c390SJed Brown if (!*L) {ierr = PetscMalloc1((an+bn),L);CHKERRQ(ierr);} 700e498c390SJed Brown for (ai=0,bi=0,k=0; ai<an || bi<bn; ) { 701e498c390SJed Brown PetscInt t = -1; 702e498c390SJed Brown for ( ; ai<an && (!bn || aI[ai] <= bI[bi]); ai++) (*L)[k++] = t = aI[ai]; 703e498c390SJed Brown for ( ; bi<bn && bI[bi] == t; bi++); 704e498c390SJed Brown for ( ; bi<bn && (!an || bI[bi] <= aI[ai]); bi++) (*L)[k++] = t = bI[bi]; 705e498c390SJed Brown for ( ; ai<an && aI[ai] == t; ai++); 706e498c390SJed Brown } 707e498c390SJed Brown *n = k; 708e498c390SJed Brown PetscFunctionReturn(0); 709e498c390SJed Brown } 710e5c89e4eSSatish Balay 7116c2863d0SBarry Smith /*@C 71242eaa7f3SBarry Smith PetscProcessTree - Prepares tree data to be displayed graphically 71342eaa7f3SBarry Smith 71442eaa7f3SBarry Smith Not Collective 71542eaa7f3SBarry Smith 71642eaa7f3SBarry Smith Input Parameters: 71742eaa7f3SBarry Smith + n - number of values 71842eaa7f3SBarry Smith . mask - indicates those entries in the tree, location 0 is always masked 71942eaa7f3SBarry Smith - parentid - indicates the parent of each entry 72042eaa7f3SBarry Smith 72142eaa7f3SBarry Smith Output Parameters: 72242eaa7f3SBarry Smith + Nlevels - the number of levels 72342eaa7f3SBarry Smith . Level - for each node tells its level 72442eaa7f3SBarry Smith . Levelcnts - the number of nodes on each level 72542eaa7f3SBarry Smith . Idbylevel - a list of ids on each of the levels, first level followed by second etc 72642eaa7f3SBarry Smith - Column - for each id tells its column index 72742eaa7f3SBarry Smith 7286c2863d0SBarry Smith Level: developer 72942eaa7f3SBarry Smith 73095452b02SPatrick Sanan Notes: 73195452b02SPatrick Sanan This code is not currently used 73242eaa7f3SBarry Smith 73342eaa7f3SBarry Smith .seealso: PetscSortReal(), PetscSortIntWithPermutation() 73442eaa7f3SBarry Smith @*/ 7357087cfbeSBarry Smith PetscErrorCode PetscProcessTree(PetscInt n,const PetscBool mask[],const PetscInt parentid[],PetscInt *Nlevels,PetscInt **Level,PetscInt **Levelcnt,PetscInt **Idbylevel,PetscInt **Column) 73642eaa7f3SBarry Smith { 73742eaa7f3SBarry Smith PetscInt i,j,cnt,nmask = 0,nlevels = 0,*level,*levelcnt,levelmax = 0,*workid,*workparentid,tcnt = 0,*idbylevel,*column; 73842eaa7f3SBarry Smith PetscErrorCode ierr; 739ace3abfcSBarry Smith PetscBool done = PETSC_FALSE; 74042eaa7f3SBarry Smith 74142eaa7f3SBarry Smith PetscFunctionBegin; 74242eaa7f3SBarry Smith if (!mask[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mask of 0th location must be set"); 74342eaa7f3SBarry Smith for (i=0; i<n; i++) { 74442eaa7f3SBarry Smith if (mask[i]) continue; 74542eaa7f3SBarry Smith if (parentid[i] == i) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Node labeled as own parent"); 74642eaa7f3SBarry Smith if (parentid[i] && mask[parentid[i]]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Parent is masked"); 74742eaa7f3SBarry Smith } 74842eaa7f3SBarry Smith 74942eaa7f3SBarry Smith for (i=0; i<n; i++) { 75042eaa7f3SBarry Smith if (!mask[i]) nmask++; 75142eaa7f3SBarry Smith } 75242eaa7f3SBarry Smith 75342eaa7f3SBarry Smith /* determine the level in the tree of each node */ 7541795a4d1SJed Brown ierr = PetscCalloc1(n,&level);CHKERRQ(ierr); 755a297a907SKarl Rupp 75642eaa7f3SBarry Smith level[0] = 1; 75742eaa7f3SBarry Smith while (!done) { 75842eaa7f3SBarry Smith done = PETSC_TRUE; 75942eaa7f3SBarry Smith for (i=0; i<n; i++) { 76042eaa7f3SBarry Smith if (mask[i]) continue; 76142eaa7f3SBarry Smith if (!level[i] && level[parentid[i]]) level[i] = level[parentid[i]] + 1; 76242eaa7f3SBarry Smith else if (!level[i]) done = PETSC_FALSE; 76342eaa7f3SBarry Smith } 76442eaa7f3SBarry Smith } 76542eaa7f3SBarry Smith for (i=0; i<n; i++) { 76642eaa7f3SBarry Smith level[i]--; 76742eaa7f3SBarry Smith nlevels = PetscMax(nlevels,level[i]); 76842eaa7f3SBarry Smith } 76942eaa7f3SBarry Smith 77042eaa7f3SBarry Smith /* count the number of nodes on each level and its max */ 7711795a4d1SJed Brown ierr = PetscCalloc1(nlevels,&levelcnt);CHKERRQ(ierr); 77242eaa7f3SBarry Smith for (i=0; i<n; i++) { 77342eaa7f3SBarry Smith if (mask[i]) continue; 77442eaa7f3SBarry Smith levelcnt[level[i]-1]++; 77542eaa7f3SBarry Smith } 776a297a907SKarl Rupp for (i=0; i<nlevels;i++) levelmax = PetscMax(levelmax,levelcnt[i]); 77742eaa7f3SBarry Smith 77842eaa7f3SBarry Smith /* for each level sort the ids by the parent id */ 779dcca6d9dSJed Brown ierr = PetscMalloc2(levelmax,&workid,levelmax,&workparentid);CHKERRQ(ierr); 780785e854fSJed Brown ierr = PetscMalloc1(nmask,&idbylevel);CHKERRQ(ierr); 78142eaa7f3SBarry Smith for (j=1; j<=nlevels;j++) { 78242eaa7f3SBarry Smith cnt = 0; 78342eaa7f3SBarry Smith for (i=0; i<n; i++) { 78442eaa7f3SBarry Smith if (mask[i]) continue; 78542eaa7f3SBarry Smith if (level[i] != j) continue; 78642eaa7f3SBarry Smith workid[cnt] = i; 78742eaa7f3SBarry Smith workparentid[cnt++] = parentid[i]; 78842eaa7f3SBarry Smith } 78942eaa7f3SBarry Smith /* PetscIntView(cnt,workparentid,0); 79042eaa7f3SBarry Smith PetscIntView(cnt,workid,0); 79142eaa7f3SBarry Smith ierr = PetscSortIntWithArray(cnt,workparentid,workid);CHKERRQ(ierr); 79242eaa7f3SBarry Smith PetscIntView(cnt,workparentid,0); 79342eaa7f3SBarry Smith PetscIntView(cnt,workid,0);*/ 794580bdb30SBarry Smith ierr = PetscArraycpy(idbylevel+tcnt,workid,cnt);CHKERRQ(ierr); 79542eaa7f3SBarry Smith tcnt += cnt; 79642eaa7f3SBarry Smith } 79742eaa7f3SBarry Smith if (tcnt != nmask) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent count of unmasked nodes"); 79842eaa7f3SBarry Smith ierr = PetscFree2(workid,workparentid);CHKERRQ(ierr); 79942eaa7f3SBarry Smith 80042eaa7f3SBarry Smith /* for each node list its column */ 801785e854fSJed Brown ierr = PetscMalloc1(n,&column);CHKERRQ(ierr); 80242eaa7f3SBarry Smith cnt = 0; 80342eaa7f3SBarry Smith for (j=0; j<nlevels; j++) { 80442eaa7f3SBarry Smith for (i=0; i<levelcnt[j]; i++) { 80542eaa7f3SBarry Smith column[idbylevel[cnt++]] = i; 80642eaa7f3SBarry Smith } 80742eaa7f3SBarry Smith } 80842eaa7f3SBarry Smith 80942eaa7f3SBarry Smith *Nlevels = nlevels; 81042eaa7f3SBarry Smith *Level = level; 81142eaa7f3SBarry Smith *Levelcnt = levelcnt; 81242eaa7f3SBarry Smith *Idbylevel = idbylevel; 81342eaa7f3SBarry Smith *Column = column; 81442eaa7f3SBarry Smith PetscFunctionReturn(0); 81542eaa7f3SBarry Smith } 816