17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay This file contains routines for sorting integers. Values are sorted in place. 4e5c89e4eSSatish Balay */ 5c6db04a5SJed Brown #include <petscsys.h> /*I "petscsys.h" I*/ 6e5c89e4eSSatish Balay 7e5c89e4eSSatish Balay #define SWAP(a,b,t) {t=a;a=b;b=t;} 8e5c89e4eSSatish Balay 9a8582168SJed Brown #define MEDIAN3(v,a,b,c) \ 10a8582168SJed Brown (v[a]<v[b] \ 11a8582168SJed Brown ? (v[b]<v[c] \ 12a8582168SJed Brown ? b \ 13a8582168SJed Brown : (v[a]<v[c] ? c : a)) \ 14a8582168SJed Brown : (v[c]<v[b] \ 15a8582168SJed Brown ? b \ 16a8582168SJed Brown : (v[a]<v[c] ? a : c))) 17a8582168SJed Brown 18a8582168SJed Brown #define MEDIAN(v,right) MEDIAN3(v,right/4,right/2,right/4*3) 19ef8e3583SJed Brown 20e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 21e5c89e4eSSatish Balay 22e5c89e4eSSatish Balay #undef __FUNCT__ 23e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortInt_Private" 24e5c89e4eSSatish Balay /* 25e5c89e4eSSatish Balay A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 26e5c89e4eSSatish Balay Assumes 0 origin for v, number of elements = right+1 (right is index of 27e5c89e4eSSatish Balay right-most member). 28e5c89e4eSSatish Balay */ 29ef8e3583SJed Brown static void PetscSortInt_Private(PetscInt *v,PetscInt right) 30e5c89e4eSSatish Balay { 31ef8e3583SJed Brown PetscInt i,j,pivot,tmp; 32e5c89e4eSSatish Balay 33e5c89e4eSSatish Balay if (right <= 1) { 34e5c89e4eSSatish Balay if (right == 1) { 35e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP(v[0],v[1],tmp); 36e5c89e4eSSatish Balay } 37ef8e3583SJed Brown return; 38e5c89e4eSSatish Balay } 39ef8e3583SJed Brown i = MEDIAN(v,right); /* Choose a pivot */ 40ef8e3583SJed Brown SWAP(v[0],v[i],tmp); /* Move it out of the way */ 41ef8e3583SJed Brown pivot = v[0]; 42ef8e3583SJed Brown for (i=0,j=right+1;;) { 43ef8e3583SJed Brown while (++i < j && v[i] <= pivot); /* Scan from the left */ 44ef8e3583SJed Brown while (v[--j] > pivot); /* Scan from the right */ 45ef8e3583SJed Brown if (i >= j) break; 46ef8e3583SJed Brown SWAP(v[i],v[j],tmp); 47e5c89e4eSSatish Balay } 48ef8e3583SJed Brown SWAP(v[0],v[j],tmp); /* Put pivot back in place. */ 49ef8e3583SJed Brown PetscSortInt_Private(v,j-1); 50ef8e3583SJed Brown PetscSortInt_Private(v+j+1,right-(j+1)); 51e5c89e4eSSatish Balay } 52e5c89e4eSSatish Balay 53e5c89e4eSSatish Balay #undef __FUNCT__ 54e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortInt" 55e5c89e4eSSatish Balay /*@ 56e5c89e4eSSatish Balay PetscSortInt - Sorts an array of integers in place in increasing order. 57e5c89e4eSSatish Balay 58e5c89e4eSSatish Balay Not Collective 59e5c89e4eSSatish Balay 60e5c89e4eSSatish Balay Input Parameters: 61e5c89e4eSSatish Balay + n - number of values 62e5c89e4eSSatish Balay - i - array of integers 63e5c89e4eSSatish Balay 64e5c89e4eSSatish Balay Level: intermediate 65e5c89e4eSSatish Balay 66e5c89e4eSSatish Balay Concepts: sorting^ints 67e5c89e4eSSatish Balay 68e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntWithPermutation() 69e5c89e4eSSatish Balay @*/ 707087cfbeSBarry Smith PetscErrorCode PetscSortInt(PetscInt n,PetscInt i[]) 71e5c89e4eSSatish Balay { 72e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 73e5c89e4eSSatish Balay 74e5c89e4eSSatish Balay PetscFunctionBegin; 75e5c89e4eSSatish Balay if (n<8) { 76e5c89e4eSSatish Balay for (k=0; k<n; k++) { 77e5c89e4eSSatish Balay ik = i[k]; 78e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 79e5c89e4eSSatish Balay if (ik > i[j]) { 80e5c89e4eSSatish Balay SWAP(i[k],i[j],tmp); 81e5c89e4eSSatish Balay ik = i[k]; 82e5c89e4eSSatish Balay } 83e5c89e4eSSatish Balay } 84e5c89e4eSSatish Balay } 85e5c89e4eSSatish Balay } else { 86ef8e3583SJed Brown PetscSortInt_Private(i,n-1); 87e5c89e4eSSatish Balay } 88e5c89e4eSSatish Balay PetscFunctionReturn(0); 89e5c89e4eSSatish Balay } 90e5c89e4eSSatish Balay 911db36a52SBarry Smith #undef __FUNCT__ 921db36a52SBarry Smith #define __FUNCT__ "PetscSortRemoveDupsInt" 931db36a52SBarry Smith /*@ 941db36a52SBarry Smith PetscSortRemoveDupsInt - Sorts an array of integers in place in increasing order removes all duplicate entries 951db36a52SBarry Smith 961db36a52SBarry Smith Not Collective 971db36a52SBarry Smith 981db36a52SBarry Smith Input Parameters: 991db36a52SBarry Smith + n - number of values 1001db36a52SBarry Smith - ii - array of integers 1011db36a52SBarry Smith 1021db36a52SBarry Smith Output Parameter: 1031db36a52SBarry Smith . n - number of non-redundant values 1041db36a52SBarry Smith 1051db36a52SBarry Smith Level: intermediate 1061db36a52SBarry Smith 1071db36a52SBarry Smith Concepts: sorting^ints 1081db36a52SBarry Smith 1091db36a52SBarry Smith .seealso: PetscSortReal(), PetscSortIntWithPermutation(), PetscSortInt() 1101db36a52SBarry Smith @*/ 1117087cfbeSBarry Smith PetscErrorCode PetscSortRemoveDupsInt(PetscInt *n,PetscInt ii[]) 1121db36a52SBarry Smith { 1131db36a52SBarry Smith PetscErrorCode ierr; 1141db36a52SBarry Smith PetscInt i,s = 0,N = *n, b = 0; 1151db36a52SBarry Smith 1161db36a52SBarry Smith PetscFunctionBegin; 1171db36a52SBarry Smith ierr = PetscSortInt(N,ii);CHKERRQ(ierr); 1181db36a52SBarry Smith for (i=0; i<N-1; i++) { 119a5891931SBarry Smith if (ii[b+s+1] != ii[b]) {ii[b+1] = ii[b+s+1]; b++;} 120a5891931SBarry Smith else s++; 1211db36a52SBarry Smith } 1221db36a52SBarry Smith *n = N - s; 1231db36a52SBarry Smith PetscFunctionReturn(0); 1241db36a52SBarry Smith } 1251db36a52SBarry Smith 126*60e03357SMatthew G Knepley #undef __FUNCT__ 127*60e03357SMatthew G Knepley #define __FUNCT__ "PetscFindInt" 128*60e03357SMatthew G Knepley /*@ 129*60e03357SMatthew G Knepley PetscFindInt - Finds and integers in a sorted array of integers 130*60e03357SMatthew G Knepley 131*60e03357SMatthew G Knepley Not Collective 132*60e03357SMatthew G Knepley 133*60e03357SMatthew G Knepley Input Parameters: 134*60e03357SMatthew G Knepley + key - the integer to locate 135*60e03357SMatthew G Knepley . n - number of value in the array 136*60e03357SMatthew G Knepley - ii - array of integers 137*60e03357SMatthew G Knepley 138*60e03357SMatthew G Knepley Output Parameter: 139*60e03357SMatthew G Knepley . loc - the location, or -1 if the value is not found 140*60e03357SMatthew G Knepley 141*60e03357SMatthew G Knepley Level: intermediate 142*60e03357SMatthew G Knepley 143*60e03357SMatthew G Knepley Concepts: sorting^ints 144*60e03357SMatthew G Knepley 145*60e03357SMatthew G Knepley .seealso: PetscSortInt(), PetscSortIntWithArray(), PetscSortRemoveDupsInt() 146*60e03357SMatthew G Knepley @*/ 147*60e03357SMatthew G Knepley PetscErrorCode PetscFindInt(PetscInt key, PetscInt n, PetscInt ii[], PetscInt *loc) 148*60e03357SMatthew G Knepley { 149*60e03357SMatthew G Knepley /* inclusive indices 150*60e03357SMatthew G Knepley 0 <= imin when using truncate toward zero divide 151*60e03357SMatthew G Knepley imid = (imin+imax)/2; 152*60e03357SMatthew G Knepley imin unrestricted when using truncate toward minus infinity divide 153*60e03357SMatthew G Knepley imid = (imin+imax)>>1; or 154*60e03357SMatthew G Knepley imid = (int)floor((imin+imax)/2.0); */ 155*60e03357SMatthew G Knepley PetscInt imin = 0, imax = n-1; 156*60e03357SMatthew G Knepley PetscErrorCode ierr; 157*60e03357SMatthew G Knepley 158*60e03357SMatthew G Knepley PetscFunctionBegin; 159*60e03357SMatthew G Knepley PetscValidPointer(ii, 3); 160*60e03357SMatthew G Knepley PetscValidPointer(loc, 4); 161*60e03357SMatthew G Knepley /* continually narrow search until just one element remains */ 162*60e03357SMatthew G Knepley while(imin < imax) { 163*60e03357SMatthew G Knepley PetscInt imid = (imin+imax)/2; 164*60e03357SMatthew G Knepley 165*60e03357SMatthew G Knepley /* code must guarantee the interval is reduced at each iteration 166*60e03357SMatthew G Knepley assert(imid < imax); */ 167*60e03357SMatthew G Knepley /* reduce the search */ 168*60e03357SMatthew G Knepley if (ii[imid] < key) { 169*60e03357SMatthew G Knepley imin = imid + 1; 170*60e03357SMatthew G Knepley } else { 171*60e03357SMatthew G Knepley imax = imid; 172*60e03357SMatthew G Knepley } 173*60e03357SMatthew G Knepley } 174*60e03357SMatthew G Knepley /* At exit of while: 175*60e03357SMatthew G Knepley if ii[] is empty, then imax < imin 176*60e03357SMatthew G Knepley otherwise imax == imin */ 177*60e03357SMatthew G Knepley /* deferred test for equality */ 178*60e03357SMatthew G Knepley if ((imax == imin) && (ii[imin] == key)) { 179*60e03357SMatthew G Knepley *loc = imin; 180*60e03357SMatthew G Knepley } else { 181*60e03357SMatthew G Knepley *loc = -1; 182*60e03357SMatthew G Knepley } 183*60e03357SMatthew G Knepley PetscFunctionReturn(0); 184*60e03357SMatthew G Knepley } 185*60e03357SMatthew G Knepley 1861db36a52SBarry Smith 187e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 188e5c89e4eSSatish Balay #define SWAP2(a,b,c,d,t) {t=a;a=b;b=t;t=c;c=d;d=t;} 189e5c89e4eSSatish Balay 190e5c89e4eSSatish Balay #undef __FUNCT__ 191e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithArray_Private" 192e5c89e4eSSatish Balay /* 193e5c89e4eSSatish Balay A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 194e5c89e4eSSatish Balay Assumes 0 origin for v, number of elements = right+1 (right is index of 195e5c89e4eSSatish Balay right-most member). 196e5c89e4eSSatish Balay */ 197e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithArray_Private(PetscInt *v,PetscInt *V,PetscInt right) 198e5c89e4eSSatish Balay { 199e5c89e4eSSatish Balay PetscErrorCode ierr; 200e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 201e5c89e4eSSatish Balay 202e5c89e4eSSatish Balay PetscFunctionBegin; 203e5c89e4eSSatish Balay if (right <= 1) { 204e5c89e4eSSatish Balay if (right == 1) { 205e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 206e5c89e4eSSatish Balay } 207e5c89e4eSSatish Balay PetscFunctionReturn(0); 208e5c89e4eSSatish Balay } 209e5c89e4eSSatish Balay SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 210e5c89e4eSSatish Balay vl = v[0]; 211e5c89e4eSSatish Balay last = 0; 212e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 213e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 214e5c89e4eSSatish Balay } 215e5c89e4eSSatish Balay SWAP2(v[0],v[last],V[0],V[last],tmp); 216e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 217e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 218e5c89e4eSSatish Balay PetscFunctionReturn(0); 219e5c89e4eSSatish Balay } 220e5c89e4eSSatish Balay 221e5c89e4eSSatish Balay #undef __FUNCT__ 222e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithArray" 223e5c89e4eSSatish Balay /*@ 224e5c89e4eSSatish Balay PetscSortIntWithArray - Sorts an array of integers in place in increasing order; 225e5c89e4eSSatish Balay changes a second array to match the sorted first array. 226e5c89e4eSSatish Balay 227e5c89e4eSSatish Balay Not Collective 228e5c89e4eSSatish Balay 229e5c89e4eSSatish Balay Input Parameters: 230e5c89e4eSSatish Balay + n - number of values 231e5c89e4eSSatish Balay . i - array of integers 232e5c89e4eSSatish Balay - I - second array of integers 233e5c89e4eSSatish Balay 234e5c89e4eSSatish Balay Level: intermediate 235e5c89e4eSSatish Balay 236e5c89e4eSSatish Balay Concepts: sorting^ints with array 237e5c89e4eSSatish Balay 238e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 239e5c89e4eSSatish Balay @*/ 2407087cfbeSBarry Smith PetscErrorCode PetscSortIntWithArray(PetscInt n,PetscInt i[],PetscInt Ii[]) 241e5c89e4eSSatish Balay { 242e5c89e4eSSatish Balay PetscErrorCode ierr; 243e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 244e5c89e4eSSatish Balay 245e5c89e4eSSatish Balay PetscFunctionBegin; 246e5c89e4eSSatish Balay if (n<8) { 247e5c89e4eSSatish Balay for (k=0; k<n; k++) { 248e5c89e4eSSatish Balay ik = i[k]; 249e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 250e5c89e4eSSatish Balay if (ik > i[j]) { 251b7940d39SSatish Balay SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 252e5c89e4eSSatish Balay ik = i[k]; 253e5c89e4eSSatish Balay } 254e5c89e4eSSatish Balay } 255e5c89e4eSSatish Balay } 256e5c89e4eSSatish Balay } else { 257b7940d39SSatish Balay ierr = PetscSortIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 258e5c89e4eSSatish Balay } 259e5c89e4eSSatish Balay PetscFunctionReturn(0); 260e5c89e4eSSatish Balay } 261e5c89e4eSSatish Balay 262c1f0200aSDmitry Karpeev 263c1f0200aSDmitry Karpeev #define SWAP3(a,b,c,d,e,f,t) {t=a;a=b;b=t;t=c;c=d;d=t;t=e;e=f;f=t;} 264c1f0200aSDmitry Karpeev 265c1f0200aSDmitry Karpeev #undef __FUNCT__ 266c1f0200aSDmitry Karpeev #define __FUNCT__ "PetscSortIntWithArrayPair_Private" 267c1f0200aSDmitry Karpeev /* 268c1f0200aSDmitry Karpeev A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 269c1f0200aSDmitry Karpeev Assumes 0 origin for v, number of elements = right+1 (right is index of 270c1f0200aSDmitry Karpeev right-most member). 271c1f0200aSDmitry Karpeev */ 272d7aa01a8SHong Zhang static PetscErrorCode PetscSortIntWithArrayPair_Private(PetscInt *L,PetscInt *J, PetscInt *K, PetscInt right) 273c1f0200aSDmitry Karpeev { 274c1f0200aSDmitry Karpeev PetscErrorCode ierr; 275c1f0200aSDmitry Karpeev PetscInt i,vl,last,tmp; 276c1f0200aSDmitry Karpeev 277c1f0200aSDmitry Karpeev PetscFunctionBegin; 278c1f0200aSDmitry Karpeev if (right <= 1) { 279c1f0200aSDmitry Karpeev if (right == 1) { 280d7aa01a8SHong Zhang if (L[0] > L[1]) SWAP3(L[0],L[1],J[0],J[1],K[0],K[1],tmp); 281c1f0200aSDmitry Karpeev } 282c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 283c1f0200aSDmitry Karpeev } 284d7aa01a8SHong Zhang SWAP3(L[0],L[right/2],J[0],J[right/2],K[0],K[right/2],tmp); 285d7aa01a8SHong Zhang vl = L[0]; 286c1f0200aSDmitry Karpeev last = 0; 287c1f0200aSDmitry Karpeev for (i=1; i<=right; i++) { 288d7aa01a8SHong Zhang if (L[i] < vl) {last++; SWAP3(L[last],L[i],J[last],J[i],K[last],K[i],tmp);} 289c1f0200aSDmitry Karpeev } 290d7aa01a8SHong Zhang SWAP3(L[0],L[last],J[0],J[last],K[0],K[last],tmp); 291d7aa01a8SHong Zhang ierr = PetscSortIntWithArrayPair_Private(L,J,K,last-1);CHKERRQ(ierr); 292d7aa01a8SHong Zhang ierr = PetscSortIntWithArrayPair_Private(L+last+1,J+last+1,K+last+1,right-(last+1));CHKERRQ(ierr); 293c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 294c1f0200aSDmitry Karpeev } 295c1f0200aSDmitry Karpeev 296c1f0200aSDmitry Karpeev #undef __FUNCT__ 297c1f0200aSDmitry Karpeev #define __FUNCT__ "PetscSortIntWithArrayPair" 298c1f0200aSDmitry Karpeev /*@ 299c1f0200aSDmitry Karpeev PetscSortIntWithArrayPair - Sorts an array of integers in place in increasing order; 300c1f0200aSDmitry Karpeev changes a pair of integer arrays to match the sorted first array. 301c1f0200aSDmitry Karpeev 302c1f0200aSDmitry Karpeev Not Collective 303c1f0200aSDmitry Karpeev 304c1f0200aSDmitry Karpeev Input Parameters: 305c1f0200aSDmitry Karpeev + n - number of values 306c1f0200aSDmitry Karpeev . I - array of integers 307c1f0200aSDmitry Karpeev . J - second array of integers (first array of the pair) 308c1f0200aSDmitry Karpeev - K - third array of integers (second array of the pair) 309c1f0200aSDmitry Karpeev 310c1f0200aSDmitry Karpeev Level: intermediate 311c1f0200aSDmitry Karpeev 312c1f0200aSDmitry Karpeev Concepts: sorting^ints with array pair 313c1f0200aSDmitry Karpeev 314c1f0200aSDmitry Karpeev .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortIntWithArray() 315c1f0200aSDmitry Karpeev @*/ 316d7aa01a8SHong Zhang PetscErrorCode PetscSortIntWithArrayPair(PetscInt n,PetscInt *L,PetscInt *J, PetscInt *K) 317c1f0200aSDmitry Karpeev { 318c1f0200aSDmitry Karpeev PetscErrorCode ierr; 319c1f0200aSDmitry Karpeev PetscInt j,k,tmp,ik; 320c1f0200aSDmitry Karpeev 321c1f0200aSDmitry Karpeev PetscFunctionBegin; 322c1f0200aSDmitry Karpeev if (n<8) { 323c1f0200aSDmitry Karpeev for (k=0; k<n; k++) { 324d7aa01a8SHong Zhang ik = L[k]; 325c1f0200aSDmitry Karpeev for (j=k+1; j<n; j++) { 326d7aa01a8SHong Zhang if (ik > L[j]) { 327d7aa01a8SHong Zhang SWAP3(L[k],L[j],J[k],J[j],K[k],K[j],tmp); 328d7aa01a8SHong Zhang ik = L[k]; 329c1f0200aSDmitry Karpeev } 330c1f0200aSDmitry Karpeev } 331c1f0200aSDmitry Karpeev } 332c1f0200aSDmitry Karpeev } else { 333d7aa01a8SHong Zhang ierr = PetscSortIntWithArrayPair_Private(L,J,K,n-1);CHKERRQ(ierr); 334c1f0200aSDmitry Karpeev } 335c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 336c1f0200aSDmitry Karpeev } 337c1f0200aSDmitry Karpeev 33817d7d925SStefano Zampini #undef __FUNCT__ 33917d7d925SStefano Zampini #define __FUNCT__ "PetscSortMPIInt_Private" 34017d7d925SStefano Zampini /* 34117d7d925SStefano Zampini A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 34217d7d925SStefano Zampini Assumes 0 origin for v, number of elements = right+1 (right is index of 34317d7d925SStefano Zampini right-most member). 34417d7d925SStefano Zampini */ 34517d7d925SStefano Zampini static void PetscSortMPIInt_Private(PetscMPIInt *v,PetscInt right) 34617d7d925SStefano Zampini { 34717d7d925SStefano Zampini PetscInt i,j; 34817d7d925SStefano Zampini PetscMPIInt pivot,tmp; 34917d7d925SStefano Zampini 35017d7d925SStefano Zampini if (right <= 1) { 35117d7d925SStefano Zampini if (right == 1) { 35217d7d925SStefano Zampini if (v[0] > v[1]) SWAP(v[0],v[1],tmp); 35317d7d925SStefano Zampini } 35417d7d925SStefano Zampini return; 35517d7d925SStefano Zampini } 35617d7d925SStefano Zampini i = MEDIAN(v,right); /* Choose a pivot */ 35717d7d925SStefano Zampini SWAP(v[0],v[i],tmp); /* Move it out of the way */ 35817d7d925SStefano Zampini pivot = v[0]; 35917d7d925SStefano Zampini for (i=0,j=right+1;;) { 36017d7d925SStefano Zampini while (++i < j && v[i] <= pivot); /* Scan from the left */ 36117d7d925SStefano Zampini while (v[--j] > pivot); /* Scan from the right */ 36217d7d925SStefano Zampini if (i >= j) break; 36317d7d925SStefano Zampini SWAP(v[i],v[j],tmp); 36417d7d925SStefano Zampini } 36517d7d925SStefano Zampini SWAP(v[0],v[j],tmp); /* Put pivot back in place. */ 36617d7d925SStefano Zampini PetscSortMPIInt_Private(v,j-1); 36717d7d925SStefano Zampini PetscSortMPIInt_Private(v+j+1,right-(j+1)); 36817d7d925SStefano Zampini } 36917d7d925SStefano Zampini 37017d7d925SStefano Zampini #undef __FUNCT__ 37117d7d925SStefano Zampini #define __FUNCT__ "PetscSortMPIInt" 37217d7d925SStefano Zampini /*@ 37317d7d925SStefano Zampini PetscSortMPIInt - Sorts an array of MPI integers in place in increasing order. 37417d7d925SStefano Zampini 37517d7d925SStefano Zampini Not Collective 37617d7d925SStefano Zampini 37717d7d925SStefano Zampini Input Parameters: 37817d7d925SStefano Zampini + n - number of values 37917d7d925SStefano Zampini - i - array of integers 38017d7d925SStefano Zampini 38117d7d925SStefano Zampini Level: intermediate 38217d7d925SStefano Zampini 38317d7d925SStefano Zampini Concepts: sorting^ints 38417d7d925SStefano Zampini 38517d7d925SStefano Zampini .seealso: PetscSortReal(), PetscSortIntWithPermutation() 38617d7d925SStefano Zampini @*/ 38717d7d925SStefano Zampini PetscErrorCode PetscSortMPIInt(PetscInt n,PetscMPIInt i[]) 38817d7d925SStefano Zampini { 38917d7d925SStefano Zampini PetscInt j,k; 39017d7d925SStefano Zampini PetscMPIInt tmp,ik; 39117d7d925SStefano Zampini 39217d7d925SStefano Zampini PetscFunctionBegin; 39317d7d925SStefano Zampini if (n<8) { 39417d7d925SStefano Zampini for (k=0; k<n; k++) { 39517d7d925SStefano Zampini ik = i[k]; 39617d7d925SStefano Zampini for (j=k+1; j<n; j++) { 39717d7d925SStefano Zampini if (ik > i[j]) { 39817d7d925SStefano Zampini SWAP(i[k],i[j],tmp); 39917d7d925SStefano Zampini ik = i[k]; 40017d7d925SStefano Zampini } 40117d7d925SStefano Zampini } 40217d7d925SStefano Zampini } 40317d7d925SStefano Zampini } else { 40417d7d925SStefano Zampini PetscSortMPIInt_Private(i,n-1); 40517d7d925SStefano Zampini } 40617d7d925SStefano Zampini PetscFunctionReturn(0); 40717d7d925SStefano Zampini } 40817d7d925SStefano Zampini 40917d7d925SStefano Zampini #undef __FUNCT__ 41017d7d925SStefano Zampini #define __FUNCT__ "PetscSortRemoveDupsMPIInt" 41117d7d925SStefano Zampini /*@ 41217d7d925SStefano Zampini PetscSortRemoveDupsMPIInt - Sorts an array of MPI integers in place in increasing order removes all duplicate entries 41317d7d925SStefano Zampini 41417d7d925SStefano Zampini Not Collective 41517d7d925SStefano Zampini 41617d7d925SStefano Zampini Input Parameters: 41717d7d925SStefano Zampini + n - number of values 41817d7d925SStefano Zampini - ii - array of integers 41917d7d925SStefano Zampini 42017d7d925SStefano Zampini Output Parameter: 42117d7d925SStefano Zampini . n - number of non-redundant values 42217d7d925SStefano Zampini 42317d7d925SStefano Zampini Level: intermediate 42417d7d925SStefano Zampini 42517d7d925SStefano Zampini Concepts: sorting^ints 42617d7d925SStefano Zampini 42717d7d925SStefano Zampini .seealso: PetscSortReal(), PetscSortIntWithPermutation(), PetscSortInt() 42817d7d925SStefano Zampini @*/ 42917d7d925SStefano Zampini PetscErrorCode PetscSortRemoveDupsMPIInt(PetscInt *n,PetscMPIInt ii[]) 43017d7d925SStefano Zampini { 43117d7d925SStefano Zampini PetscErrorCode ierr; 43217d7d925SStefano Zampini PetscInt i,s = 0,N = *n, b = 0; 43317d7d925SStefano Zampini 43417d7d925SStefano Zampini PetscFunctionBegin; 43517d7d925SStefano Zampini ierr = PetscSortMPIInt(N,ii);CHKERRQ(ierr); 43617d7d925SStefano Zampini for (i=0; i<N-1; i++) { 43717d7d925SStefano Zampini if (ii[b+s+1] != ii[b]) {ii[b+1] = ii[b+s+1]; b++;} 43817d7d925SStefano Zampini else s++; 43917d7d925SStefano Zampini } 44017d7d925SStefano Zampini *n = N - s; 44117d7d925SStefano Zampini PetscFunctionReturn(0); 44217d7d925SStefano Zampini } 443c1f0200aSDmitry Karpeev 4444d615ea0SBarry Smith #undef __FUNCT__ 4454d615ea0SBarry Smith #define __FUNCT__ "PetscSortMPIIntWithArray_Private" 4464d615ea0SBarry Smith /* 4474d615ea0SBarry Smith A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 4484d615ea0SBarry Smith Assumes 0 origin for v, number of elements = right+1 (right is index of 4494d615ea0SBarry Smith right-most member). 4504d615ea0SBarry Smith */ 4514d615ea0SBarry Smith static PetscErrorCode PetscSortMPIIntWithArray_Private(PetscMPIInt *v,PetscMPIInt *V,PetscMPIInt right) 4524d615ea0SBarry Smith { 4534d615ea0SBarry Smith PetscErrorCode ierr; 4544d615ea0SBarry Smith PetscMPIInt i,vl,last,tmp; 4554d615ea0SBarry Smith 4564d615ea0SBarry Smith PetscFunctionBegin; 4574d615ea0SBarry Smith if (right <= 1) { 4584d615ea0SBarry Smith if (right == 1) { 4594d615ea0SBarry Smith if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 4604d615ea0SBarry Smith } 4614d615ea0SBarry Smith PetscFunctionReturn(0); 4624d615ea0SBarry Smith } 4634d615ea0SBarry Smith SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 4644d615ea0SBarry Smith vl = v[0]; 4654d615ea0SBarry Smith last = 0; 4664d615ea0SBarry Smith for (i=1; i<=right; i++) { 4674d615ea0SBarry Smith if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 4684d615ea0SBarry Smith } 4694d615ea0SBarry Smith SWAP2(v[0],v[last],V[0],V[last],tmp); 4704d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 4714d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 4724d615ea0SBarry Smith PetscFunctionReturn(0); 4734d615ea0SBarry Smith } 4744d615ea0SBarry Smith 4754d615ea0SBarry Smith #undef __FUNCT__ 4764d615ea0SBarry Smith #define __FUNCT__ "PetscSortMPIIntWithArray" 4774d615ea0SBarry Smith /*@ 4784d615ea0SBarry Smith PetscSortMPIIntWithArray - Sorts an array of integers in place in increasing order; 4794d615ea0SBarry Smith changes a second array to match the sorted first array. 4804d615ea0SBarry Smith 4814d615ea0SBarry Smith Not Collective 4824d615ea0SBarry Smith 4834d615ea0SBarry Smith Input Parameters: 4844d615ea0SBarry Smith + n - number of values 4854d615ea0SBarry Smith . i - array of integers 4864d615ea0SBarry Smith - I - second array of integers 4874d615ea0SBarry Smith 4884d615ea0SBarry Smith Level: intermediate 4894d615ea0SBarry Smith 4904d615ea0SBarry Smith Concepts: sorting^ints with array 4914d615ea0SBarry Smith 4924d615ea0SBarry Smith .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 4934d615ea0SBarry Smith @*/ 4947087cfbeSBarry Smith PetscErrorCode PetscSortMPIIntWithArray(PetscMPIInt n,PetscMPIInt i[],PetscMPIInt Ii[]) 4954d615ea0SBarry Smith { 4964d615ea0SBarry Smith PetscErrorCode ierr; 4974d615ea0SBarry Smith PetscMPIInt j,k,tmp,ik; 4984d615ea0SBarry Smith 4994d615ea0SBarry Smith PetscFunctionBegin; 5004d615ea0SBarry Smith if (n<8) { 5014d615ea0SBarry Smith for (k=0; k<n; k++) { 5024d615ea0SBarry Smith ik = i[k]; 5034d615ea0SBarry Smith for (j=k+1; j<n; j++) { 5044d615ea0SBarry Smith if (ik > i[j]) { 5054d615ea0SBarry Smith SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 5064d615ea0SBarry Smith ik = i[k]; 5074d615ea0SBarry Smith } 5084d615ea0SBarry Smith } 5094d615ea0SBarry Smith } 5104d615ea0SBarry Smith } else { 5114d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 5124d615ea0SBarry Smith } 5134d615ea0SBarry Smith PetscFunctionReturn(0); 5144d615ea0SBarry Smith } 5154d615ea0SBarry Smith 516e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 517e5c89e4eSSatish Balay #define SWAP2IntScalar(a,b,c,d,t,ts) {t=a;a=b;b=t;ts=c;c=d;d=ts;} 518e5c89e4eSSatish Balay 519e5c89e4eSSatish Balay #undef __FUNCT__ 520e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithScalarArray_Private" 521e5c89e4eSSatish Balay /* 522e5c89e4eSSatish Balay Modified from PetscSortIntWithArray_Private(). 523e5c89e4eSSatish Balay */ 524e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithScalarArray_Private(PetscInt *v,PetscScalar *V,PetscInt right) 525e5c89e4eSSatish Balay { 526e5c89e4eSSatish Balay PetscErrorCode ierr; 527e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 528e5c89e4eSSatish Balay PetscScalar stmp; 529e5c89e4eSSatish Balay 530e5c89e4eSSatish Balay PetscFunctionBegin; 531e5c89e4eSSatish Balay if (right <= 1) { 532e5c89e4eSSatish Balay if (right == 1) { 533e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2IntScalar(v[0],v[1],V[0],V[1],tmp,stmp); 534e5c89e4eSSatish Balay } 535e5c89e4eSSatish Balay PetscFunctionReturn(0); 536e5c89e4eSSatish Balay } 537e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[right/2],V[0],V[right/2],tmp,stmp); 538e5c89e4eSSatish Balay vl = v[0]; 539e5c89e4eSSatish Balay last = 0; 540e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 541e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2IntScalar(v[last],v[i],V[last],V[i],tmp,stmp);} 542e5c89e4eSSatish Balay } 543e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[last],V[0],V[last],tmp,stmp); 544e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v,V,last-1);CHKERRQ(ierr); 545e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 546e5c89e4eSSatish Balay PetscFunctionReturn(0); 547e5c89e4eSSatish Balay } 548e5c89e4eSSatish Balay 549e5c89e4eSSatish Balay #undef __FUNCT__ 550e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithScalarArray" 551e5c89e4eSSatish Balay /*@ 552e5c89e4eSSatish Balay PetscSortIntWithScalarArray - Sorts an array of integers in place in increasing order; 553e5c89e4eSSatish Balay changes a second SCALAR array to match the sorted first INTEGER array. 554e5c89e4eSSatish Balay 555e5c89e4eSSatish Balay Not Collective 556e5c89e4eSSatish Balay 557e5c89e4eSSatish Balay Input Parameters: 558e5c89e4eSSatish Balay + n - number of values 559e5c89e4eSSatish Balay . i - array of integers 560e5c89e4eSSatish Balay - I - second array of scalars 561e5c89e4eSSatish Balay 562e5c89e4eSSatish Balay Level: intermediate 563e5c89e4eSSatish Balay 564e5c89e4eSSatish Balay Concepts: sorting^ints with array 565e5c89e4eSSatish Balay 566e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 567e5c89e4eSSatish Balay @*/ 5687087cfbeSBarry Smith PetscErrorCode PetscSortIntWithScalarArray(PetscInt n,PetscInt i[],PetscScalar Ii[]) 569e5c89e4eSSatish Balay { 570e5c89e4eSSatish Balay PetscErrorCode ierr; 571e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 572e5c89e4eSSatish Balay PetscScalar stmp; 573e5c89e4eSSatish Balay 574e5c89e4eSSatish Balay PetscFunctionBegin; 575e5c89e4eSSatish Balay if (n<8) { 576e5c89e4eSSatish Balay for (k=0; k<n; k++) { 577e5c89e4eSSatish Balay ik = i[k]; 578e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 579e5c89e4eSSatish Balay if (ik > i[j]) { 580b7940d39SSatish Balay SWAP2IntScalar(i[k],i[j],Ii[k],Ii[j],tmp,stmp); 581e5c89e4eSSatish Balay ik = i[k]; 582e5c89e4eSSatish Balay } 583e5c89e4eSSatish Balay } 584e5c89e4eSSatish Balay } 585e5c89e4eSSatish Balay } else { 586b7940d39SSatish Balay ierr = PetscSortIntWithScalarArray_Private(i,Ii,n-1);CHKERRQ(ierr); 587e5c89e4eSSatish Balay } 588e5c89e4eSSatish Balay PetscFunctionReturn(0); 589e5c89e4eSSatish Balay } 590e5c89e4eSSatish Balay 591b4301105SBarry Smith 592b4301105SBarry Smith 593b4301105SBarry Smith #undef __FUNCT__ 594c1f0200aSDmitry Karpeev #define __FUNCT__ "PetscMergeIntArrayPair" 595c1f0200aSDmitry Karpeev /*@ 596c1f0200aSDmitry Karpeev PetscMergeIntArrayPair - Merges two SORTED integer arrays along with an additional array of integers. 597c1f0200aSDmitry Karpeev The additional arrays are the same length as sorted arrays and are merged 598c1f0200aSDmitry Karpeev in the order determined by the merging of the sorted pair. 599c1f0200aSDmitry Karpeev 600c1f0200aSDmitry Karpeev Not Collective 601c1f0200aSDmitry Karpeev 602c1f0200aSDmitry Karpeev Input Parameters: 603c1f0200aSDmitry Karpeev + an - number of values in the first array 604c1f0200aSDmitry Karpeev . aI - first sorted array of integers 605c1f0200aSDmitry Karpeev . aJ - first additional array of integers 606c1f0200aSDmitry Karpeev . bn - number of values in the second array 607c1f0200aSDmitry Karpeev . bI - second array of integers 608c1f0200aSDmitry Karpeev - bJ - second additional of integers 609c1f0200aSDmitry Karpeev 610c1f0200aSDmitry Karpeev Output Parameters: 611c1f0200aSDmitry Karpeev + n - number of values in the merged array (== an + bn) 612c1f0200aSDmitry Karpeev . I - merged sorted array 613c1f0200aSDmitry Karpeev - J - merged additional array 614c1f0200aSDmitry Karpeev 615c1f0200aSDmitry Karpeev Level: intermediate 616c1f0200aSDmitry Karpeev 617c1f0200aSDmitry Karpeev Concepts: merging^arrays 618c1f0200aSDmitry Karpeev 619c1f0200aSDmitry Karpeev .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 620c1f0200aSDmitry Karpeev @*/ 621d7aa01a8SHong Zhang PetscErrorCode PetscMergeIntArrayPair(PetscInt an,const PetscInt *aI, const PetscInt *aJ, PetscInt bn, const PetscInt *bI, const PetscInt *bJ, PetscInt *n, PetscInt **L, PetscInt **J) 622c1f0200aSDmitry Karpeev { 623c1f0200aSDmitry Karpeev PetscErrorCode ierr; 624d7aa01a8SHong Zhang PetscInt n_, *L_ = *L, *J_= *J, ak, bk, k; 625c1f0200aSDmitry Karpeev 626c1f0200aSDmitry Karpeev n_ = an + bn; 627c1f0200aSDmitry Karpeev *n = n_; 628d7aa01a8SHong Zhang if (!L_) { 629d7aa01a8SHong Zhang ierr = PetscMalloc(n_*sizeof(PetscInt), L); CHKERRQ(ierr); 630d7aa01a8SHong Zhang L_ = *L; 631c1f0200aSDmitry Karpeev } 632c1f0200aSDmitry Karpeev if (!J_){ 633c1f0200aSDmitry Karpeev ierr = PetscMalloc(n_*sizeof(PetscInt), &J_); CHKERRQ(ierr); 634c1f0200aSDmitry Karpeev J_ = *J; 635c1f0200aSDmitry Karpeev } 636c1f0200aSDmitry Karpeev k = ak = bk = 0; 637c1f0200aSDmitry Karpeev while(ak < an && bk < bn) { 638c1f0200aSDmitry Karpeev if (aI[ak] <= bI[bk]) { 639d7aa01a8SHong Zhang L_[k] = aI[ak]; 640c1f0200aSDmitry Karpeev J_[k] = aJ[ak]; 641c1f0200aSDmitry Karpeev ++ak; 642c1f0200aSDmitry Karpeev ++k; 643c1f0200aSDmitry Karpeev } 644c1f0200aSDmitry Karpeev else { 645d7aa01a8SHong Zhang L_[k] = bI[bk]; 646c1f0200aSDmitry Karpeev J_[k] = bJ[bk]; 647c1f0200aSDmitry Karpeev ++bk; 648c1f0200aSDmitry Karpeev ++k; 649c1f0200aSDmitry Karpeev } 650c1f0200aSDmitry Karpeev } 651c1f0200aSDmitry Karpeev if (ak < an) { 652d7aa01a8SHong Zhang ierr = PetscMemcpy(L_+k,aI+ak,(an-ak)*sizeof(PetscInt)); CHKERRQ(ierr); 653c1f0200aSDmitry Karpeev ierr = PetscMemcpy(J_+k,aJ+ak,(an-ak)*sizeof(PetscInt)); CHKERRQ(ierr); 654c1f0200aSDmitry Karpeev k += (an-ak); 655c1f0200aSDmitry Karpeev } 656c1f0200aSDmitry Karpeev if (bk < bn) { 657d7aa01a8SHong Zhang ierr = PetscMemcpy(L_+k,bI+bk,(bn-bk)*sizeof(PetscInt)); CHKERRQ(ierr); 658c1f0200aSDmitry Karpeev ierr = PetscMemcpy(J_+k,bJ+bk,(bn-bk)*sizeof(PetscInt)); CHKERRQ(ierr); 659c1f0200aSDmitry Karpeev k += (bn-bk); 660c1f0200aSDmitry Karpeev } 661c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 662c1f0200aSDmitry Karpeev } 663c1f0200aSDmitry Karpeev 664e5c89e4eSSatish Balay 66542eaa7f3SBarry Smith #undef __FUNCT__ 66642eaa7f3SBarry Smith #define __FUNCT__ "PetscProcessTree" 66742eaa7f3SBarry Smith /*@ 66842eaa7f3SBarry Smith PetscProcessTree - Prepares tree data to be displayed graphically 66942eaa7f3SBarry Smith 67042eaa7f3SBarry Smith Not Collective 67142eaa7f3SBarry Smith 67242eaa7f3SBarry Smith Input Parameters: 67342eaa7f3SBarry Smith + n - number of values 67442eaa7f3SBarry Smith . mask - indicates those entries in the tree, location 0 is always masked 67542eaa7f3SBarry Smith - parentid - indicates the parent of each entry 67642eaa7f3SBarry Smith 67742eaa7f3SBarry Smith Output Parameters: 67842eaa7f3SBarry Smith + Nlevels - the number of levels 67942eaa7f3SBarry Smith . Level - for each node tells its level 68042eaa7f3SBarry Smith . Levelcnts - the number of nodes on each level 68142eaa7f3SBarry Smith . Idbylevel - a list of ids on each of the levels, first level followed by second etc 68242eaa7f3SBarry Smith - Column - for each id tells its column index 68342eaa7f3SBarry Smith 68442eaa7f3SBarry Smith Level: intermediate 68542eaa7f3SBarry Smith 68642eaa7f3SBarry Smith 68742eaa7f3SBarry Smith .seealso: PetscSortReal(), PetscSortIntWithPermutation() 68842eaa7f3SBarry Smith @*/ 6897087cfbeSBarry Smith PetscErrorCode PetscProcessTree(PetscInt n,const PetscBool mask[],const PetscInt parentid[],PetscInt *Nlevels,PetscInt **Level,PetscInt **Levelcnt,PetscInt **Idbylevel,PetscInt **Column) 69042eaa7f3SBarry Smith { 69142eaa7f3SBarry Smith PetscInt i,j,cnt,nmask = 0,nlevels = 0,*level,*levelcnt,levelmax = 0,*workid,*workparentid,tcnt = 0,*idbylevel,*column; 69242eaa7f3SBarry Smith PetscErrorCode ierr; 693ace3abfcSBarry Smith PetscBool done = PETSC_FALSE; 69442eaa7f3SBarry Smith 69542eaa7f3SBarry Smith PetscFunctionBegin; 69642eaa7f3SBarry Smith if (!mask[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mask of 0th location must be set"); 69742eaa7f3SBarry Smith for (i=0; i<n; i++) { 69842eaa7f3SBarry Smith if (mask[i]) continue; 69942eaa7f3SBarry Smith if (parentid[i] == i) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Node labeled as own parent"); 70042eaa7f3SBarry Smith if (parentid[i] && mask[parentid[i]]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Parent is masked"); 70142eaa7f3SBarry Smith } 70242eaa7f3SBarry Smith 70342eaa7f3SBarry Smith 70442eaa7f3SBarry Smith for (i=0; i<n; i++) { 70542eaa7f3SBarry Smith if (!mask[i]) nmask++; 70642eaa7f3SBarry Smith } 70742eaa7f3SBarry Smith 70842eaa7f3SBarry Smith /* determine the level in the tree of each node */ 70942eaa7f3SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&level);CHKERRQ(ierr); 71042eaa7f3SBarry Smith ierr = PetscMemzero(level,n*sizeof(PetscInt));CHKERRQ(ierr); 71142eaa7f3SBarry Smith level[0] = 1; 71242eaa7f3SBarry Smith while (!done) { 71342eaa7f3SBarry Smith done = PETSC_TRUE; 71442eaa7f3SBarry Smith for (i=0; i<n; i++) { 71542eaa7f3SBarry Smith if (mask[i]) continue; 71642eaa7f3SBarry Smith if (!level[i] && level[parentid[i]]) level[i] = level[parentid[i]] + 1; 71742eaa7f3SBarry Smith else if (!level[i]) done = PETSC_FALSE; 71842eaa7f3SBarry Smith } 71942eaa7f3SBarry Smith } 72042eaa7f3SBarry Smith for (i=0; i<n; i++) { 72142eaa7f3SBarry Smith level[i]--; 72242eaa7f3SBarry Smith nlevels = PetscMax(nlevels,level[i]); 72342eaa7f3SBarry Smith } 72442eaa7f3SBarry Smith 72542eaa7f3SBarry Smith /* count the number of nodes on each level and its max */ 72642eaa7f3SBarry Smith ierr = PetscMalloc(nlevels*sizeof(PetscInt),&levelcnt);CHKERRQ(ierr); 72742eaa7f3SBarry Smith ierr = PetscMemzero(levelcnt,nlevels*sizeof(PetscInt));CHKERRQ(ierr); 72842eaa7f3SBarry Smith for (i=0; i<n; i++) { 72942eaa7f3SBarry Smith if (mask[i]) continue; 73042eaa7f3SBarry Smith levelcnt[level[i]-1]++; 73142eaa7f3SBarry Smith } 73242eaa7f3SBarry Smith for (i=0; i<nlevels;i++) { 73342eaa7f3SBarry Smith levelmax = PetscMax(levelmax,levelcnt[i]); 73442eaa7f3SBarry Smith } 73542eaa7f3SBarry Smith 73642eaa7f3SBarry Smith /* for each level sort the ids by the parent id */ 73742eaa7f3SBarry Smith ierr = PetscMalloc2(levelmax,PetscInt,&workid,levelmax,PetscInt,&workparentid);CHKERRQ(ierr); 73842eaa7f3SBarry Smith ierr = PetscMalloc(nmask*sizeof(PetscInt),&idbylevel);CHKERRQ(ierr); 73942eaa7f3SBarry Smith for (j=1; j<=nlevels;j++) { 74042eaa7f3SBarry Smith cnt = 0; 74142eaa7f3SBarry Smith for (i=0; i<n; i++) { 74242eaa7f3SBarry Smith if (mask[i]) continue; 74342eaa7f3SBarry Smith if (level[i] != j) continue; 74442eaa7f3SBarry Smith workid[cnt] = i; 74542eaa7f3SBarry Smith workparentid[cnt++] = parentid[i]; 74642eaa7f3SBarry Smith } 74742eaa7f3SBarry Smith /* PetscIntView(cnt,workparentid,0); 74842eaa7f3SBarry Smith PetscIntView(cnt,workid,0); 74942eaa7f3SBarry Smith ierr = PetscSortIntWithArray(cnt,workparentid,workid);CHKERRQ(ierr); 75042eaa7f3SBarry Smith PetscIntView(cnt,workparentid,0); 75142eaa7f3SBarry Smith PetscIntView(cnt,workid,0);*/ 75242eaa7f3SBarry Smith ierr = PetscMemcpy(idbylevel+tcnt,workid,cnt*sizeof(PetscInt));CHKERRQ(ierr); 75342eaa7f3SBarry Smith tcnt += cnt; 75442eaa7f3SBarry Smith } 75542eaa7f3SBarry Smith if (tcnt != nmask) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent count of unmasked nodes"); 75642eaa7f3SBarry Smith ierr = PetscFree2(workid,workparentid);CHKERRQ(ierr); 75742eaa7f3SBarry Smith 75842eaa7f3SBarry Smith /* for each node list its column */ 75942eaa7f3SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&column);CHKERRQ(ierr); 76042eaa7f3SBarry Smith cnt = 0; 76142eaa7f3SBarry Smith for (j=0; j<nlevels; j++) { 76242eaa7f3SBarry Smith for (i=0; i<levelcnt[j]; i++) { 76342eaa7f3SBarry Smith column[idbylevel[cnt++]] = i; 76442eaa7f3SBarry Smith } 76542eaa7f3SBarry Smith } 76642eaa7f3SBarry Smith 76742eaa7f3SBarry Smith *Nlevels = nlevels; 76842eaa7f3SBarry Smith *Level = level; 76942eaa7f3SBarry Smith *Levelcnt = levelcnt; 77042eaa7f3SBarry Smith *Idbylevel = idbylevel; 77142eaa7f3SBarry Smith *Column = column; 77242eaa7f3SBarry Smith PetscFunctionReturn(0); 77342eaa7f3SBarry Smith } 774