1*7d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay This file contains routines for sorting integers. Values are sorted in place. 4e5c89e4eSSatish Balay */ 5d382aafbSBarry Smith #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 1261db36a52SBarry Smith 127e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 128e5c89e4eSSatish Balay #define SWAP2(a,b,c,d,t) {t=a;a=b;b=t;t=c;c=d;d=t;} 129e5c89e4eSSatish Balay 130e5c89e4eSSatish Balay #undef __FUNCT__ 131e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithArray_Private" 132e5c89e4eSSatish Balay /* 133e5c89e4eSSatish Balay A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 134e5c89e4eSSatish Balay Assumes 0 origin for v, number of elements = right+1 (right is index of 135e5c89e4eSSatish Balay right-most member). 136e5c89e4eSSatish Balay */ 137e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithArray_Private(PetscInt *v,PetscInt *V,PetscInt right) 138e5c89e4eSSatish Balay { 139e5c89e4eSSatish Balay PetscErrorCode ierr; 140e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 141e5c89e4eSSatish Balay 142e5c89e4eSSatish Balay PetscFunctionBegin; 143e5c89e4eSSatish Balay if (right <= 1) { 144e5c89e4eSSatish Balay if (right == 1) { 145e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 146e5c89e4eSSatish Balay } 147e5c89e4eSSatish Balay PetscFunctionReturn(0); 148e5c89e4eSSatish Balay } 149e5c89e4eSSatish Balay SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 150e5c89e4eSSatish Balay vl = v[0]; 151e5c89e4eSSatish Balay last = 0; 152e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 153e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 154e5c89e4eSSatish Balay } 155e5c89e4eSSatish Balay SWAP2(v[0],v[last],V[0],V[last],tmp); 156e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 157e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 158e5c89e4eSSatish Balay PetscFunctionReturn(0); 159e5c89e4eSSatish Balay } 160e5c89e4eSSatish Balay 161e5c89e4eSSatish Balay #undef __FUNCT__ 162e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithArray" 163e5c89e4eSSatish Balay /*@ 164e5c89e4eSSatish Balay PetscSortIntWithArray - Sorts an array of integers in place in increasing order; 165e5c89e4eSSatish Balay changes a second array to match the sorted first array. 166e5c89e4eSSatish Balay 167e5c89e4eSSatish Balay Not Collective 168e5c89e4eSSatish Balay 169e5c89e4eSSatish Balay Input Parameters: 170e5c89e4eSSatish Balay + n - number of values 171e5c89e4eSSatish Balay . i - array of integers 172e5c89e4eSSatish Balay - I - second array of integers 173e5c89e4eSSatish Balay 174e5c89e4eSSatish Balay Level: intermediate 175e5c89e4eSSatish Balay 176e5c89e4eSSatish Balay Concepts: sorting^ints with array 177e5c89e4eSSatish Balay 178e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 179e5c89e4eSSatish Balay @*/ 1807087cfbeSBarry Smith PetscErrorCode PetscSortIntWithArray(PetscInt n,PetscInt i[],PetscInt Ii[]) 181e5c89e4eSSatish Balay { 182e5c89e4eSSatish Balay PetscErrorCode ierr; 183e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 184e5c89e4eSSatish Balay 185e5c89e4eSSatish Balay PetscFunctionBegin; 186e5c89e4eSSatish Balay if (n<8) { 187e5c89e4eSSatish Balay for (k=0; k<n; k++) { 188e5c89e4eSSatish Balay ik = i[k]; 189e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 190e5c89e4eSSatish Balay if (ik > i[j]) { 191b7940d39SSatish Balay SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 192e5c89e4eSSatish Balay ik = i[k]; 193e5c89e4eSSatish Balay } 194e5c89e4eSSatish Balay } 195e5c89e4eSSatish Balay } 196e5c89e4eSSatish Balay } else { 197b7940d39SSatish Balay ierr = PetscSortIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 198e5c89e4eSSatish Balay } 199e5c89e4eSSatish Balay PetscFunctionReturn(0); 200e5c89e4eSSatish Balay } 201e5c89e4eSSatish Balay 2024d615ea0SBarry Smith #undef __FUNCT__ 2034d615ea0SBarry Smith #define __FUNCT__ "PetscSortMPIIntWithArray_Private" 2044d615ea0SBarry Smith /* 2054d615ea0SBarry Smith A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 2064d615ea0SBarry Smith Assumes 0 origin for v, number of elements = right+1 (right is index of 2074d615ea0SBarry Smith right-most member). 2084d615ea0SBarry Smith */ 2094d615ea0SBarry Smith static PetscErrorCode PetscSortMPIIntWithArray_Private(PetscMPIInt *v,PetscMPIInt *V,PetscMPIInt right) 2104d615ea0SBarry Smith { 2114d615ea0SBarry Smith PetscErrorCode ierr; 2124d615ea0SBarry Smith PetscMPIInt i,vl,last,tmp; 2134d615ea0SBarry Smith 2144d615ea0SBarry Smith PetscFunctionBegin; 2154d615ea0SBarry Smith if (right <= 1) { 2164d615ea0SBarry Smith if (right == 1) { 2174d615ea0SBarry Smith if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 2184d615ea0SBarry Smith } 2194d615ea0SBarry Smith PetscFunctionReturn(0); 2204d615ea0SBarry Smith } 2214d615ea0SBarry Smith SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 2224d615ea0SBarry Smith vl = v[0]; 2234d615ea0SBarry Smith last = 0; 2244d615ea0SBarry Smith for (i=1; i<=right; i++) { 2254d615ea0SBarry Smith if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 2264d615ea0SBarry Smith } 2274d615ea0SBarry Smith SWAP2(v[0],v[last],V[0],V[last],tmp); 2284d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 2294d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 2304d615ea0SBarry Smith PetscFunctionReturn(0); 2314d615ea0SBarry Smith } 2324d615ea0SBarry Smith 2334d615ea0SBarry Smith #undef __FUNCT__ 2344d615ea0SBarry Smith #define __FUNCT__ "PetscSortMPIIntWithArray" 2354d615ea0SBarry Smith /*@ 2364d615ea0SBarry Smith PetscSortMPIIntWithArray - Sorts an array of integers in place in increasing order; 2374d615ea0SBarry Smith changes a second array to match the sorted first array. 2384d615ea0SBarry Smith 2394d615ea0SBarry Smith Not Collective 2404d615ea0SBarry Smith 2414d615ea0SBarry Smith Input Parameters: 2424d615ea0SBarry Smith + n - number of values 2434d615ea0SBarry Smith . i - array of integers 2444d615ea0SBarry Smith - I - second array of integers 2454d615ea0SBarry Smith 2464d615ea0SBarry Smith Level: intermediate 2474d615ea0SBarry Smith 2484d615ea0SBarry Smith Concepts: sorting^ints with array 2494d615ea0SBarry Smith 2504d615ea0SBarry Smith .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 2514d615ea0SBarry Smith @*/ 2527087cfbeSBarry Smith PetscErrorCode PetscSortMPIIntWithArray(PetscMPIInt n,PetscMPIInt i[],PetscMPIInt Ii[]) 2534d615ea0SBarry Smith { 2544d615ea0SBarry Smith PetscErrorCode ierr; 2554d615ea0SBarry Smith PetscMPIInt j,k,tmp,ik; 2564d615ea0SBarry Smith 2574d615ea0SBarry Smith PetscFunctionBegin; 2584d615ea0SBarry Smith if (n<8) { 2594d615ea0SBarry Smith for (k=0; k<n; k++) { 2604d615ea0SBarry Smith ik = i[k]; 2614d615ea0SBarry Smith for (j=k+1; j<n; j++) { 2624d615ea0SBarry Smith if (ik > i[j]) { 2634d615ea0SBarry Smith SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 2644d615ea0SBarry Smith ik = i[k]; 2654d615ea0SBarry Smith } 2664d615ea0SBarry Smith } 2674d615ea0SBarry Smith } 2684d615ea0SBarry Smith } else { 2694d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 2704d615ea0SBarry Smith } 2714d615ea0SBarry Smith PetscFunctionReturn(0); 2724d615ea0SBarry Smith } 2734d615ea0SBarry Smith 274e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 275e5c89e4eSSatish Balay #define SWAP2IntScalar(a,b,c,d,t,ts) {t=a;a=b;b=t;ts=c;c=d;d=ts;} 276e5c89e4eSSatish Balay 277e5c89e4eSSatish Balay #undef __FUNCT__ 278e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithScalarArray_Private" 279e5c89e4eSSatish Balay /* 280e5c89e4eSSatish Balay Modified from PetscSortIntWithArray_Private(). 281e5c89e4eSSatish Balay */ 282e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithScalarArray_Private(PetscInt *v,PetscScalar *V,PetscInt right) 283e5c89e4eSSatish Balay { 284e5c89e4eSSatish Balay PetscErrorCode ierr; 285e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 286e5c89e4eSSatish Balay PetscScalar stmp; 287e5c89e4eSSatish Balay 288e5c89e4eSSatish Balay PetscFunctionBegin; 289e5c89e4eSSatish Balay if (right <= 1) { 290e5c89e4eSSatish Balay if (right == 1) { 291e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2IntScalar(v[0],v[1],V[0],V[1],tmp,stmp); 292e5c89e4eSSatish Balay } 293e5c89e4eSSatish Balay PetscFunctionReturn(0); 294e5c89e4eSSatish Balay } 295e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[right/2],V[0],V[right/2],tmp,stmp); 296e5c89e4eSSatish Balay vl = v[0]; 297e5c89e4eSSatish Balay last = 0; 298e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 299e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2IntScalar(v[last],v[i],V[last],V[i],tmp,stmp);} 300e5c89e4eSSatish Balay } 301e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[last],V[0],V[last],tmp,stmp); 302e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v,V,last-1);CHKERRQ(ierr); 303e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 304e5c89e4eSSatish Balay PetscFunctionReturn(0); 305e5c89e4eSSatish Balay } 306e5c89e4eSSatish Balay 307e5c89e4eSSatish Balay #undef __FUNCT__ 308e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithScalarArray" 309e5c89e4eSSatish Balay /*@ 310e5c89e4eSSatish Balay PetscSortIntWithScalarArray - Sorts an array of integers in place in increasing order; 311e5c89e4eSSatish Balay changes a second SCALAR array to match the sorted first INTEGER array. 312e5c89e4eSSatish Balay 313e5c89e4eSSatish Balay Not Collective 314e5c89e4eSSatish Balay 315e5c89e4eSSatish Balay Input Parameters: 316e5c89e4eSSatish Balay + n - number of values 317e5c89e4eSSatish Balay . i - array of integers 318e5c89e4eSSatish Balay - I - second array of scalars 319e5c89e4eSSatish Balay 320e5c89e4eSSatish Balay Level: intermediate 321e5c89e4eSSatish Balay 322e5c89e4eSSatish Balay Concepts: sorting^ints with array 323e5c89e4eSSatish Balay 324e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 325e5c89e4eSSatish Balay @*/ 3267087cfbeSBarry Smith PetscErrorCode PetscSortIntWithScalarArray(PetscInt n,PetscInt i[],PetscScalar Ii[]) 327e5c89e4eSSatish Balay { 328e5c89e4eSSatish Balay PetscErrorCode ierr; 329e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 330e5c89e4eSSatish Balay PetscScalar stmp; 331e5c89e4eSSatish Balay 332e5c89e4eSSatish Balay PetscFunctionBegin; 333e5c89e4eSSatish Balay if (n<8) { 334e5c89e4eSSatish Balay for (k=0; k<n; k++) { 335e5c89e4eSSatish Balay ik = i[k]; 336e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 337e5c89e4eSSatish Balay if (ik > i[j]) { 338b7940d39SSatish Balay SWAP2IntScalar(i[k],i[j],Ii[k],Ii[j],tmp,stmp); 339e5c89e4eSSatish Balay ik = i[k]; 340e5c89e4eSSatish Balay } 341e5c89e4eSSatish Balay } 342e5c89e4eSSatish Balay } 343e5c89e4eSSatish Balay } else { 344b7940d39SSatish Balay ierr = PetscSortIntWithScalarArray_Private(i,Ii,n-1);CHKERRQ(ierr); 345e5c89e4eSSatish Balay } 346e5c89e4eSSatish Balay PetscFunctionReturn(0); 347e5c89e4eSSatish Balay } 348e5c89e4eSSatish Balay 349e5c89e4eSSatish Balay 35042eaa7f3SBarry Smith #undef __FUNCT__ 35142eaa7f3SBarry Smith #define __FUNCT__ "PetscProcessTree" 35242eaa7f3SBarry Smith /*@ 35342eaa7f3SBarry Smith PetscProcessTree - Prepares tree data to be displayed graphically 35442eaa7f3SBarry Smith 35542eaa7f3SBarry Smith Not Collective 35642eaa7f3SBarry Smith 35742eaa7f3SBarry Smith Input Parameters: 35842eaa7f3SBarry Smith + n - number of values 35942eaa7f3SBarry Smith . mask - indicates those entries in the tree, location 0 is always masked 36042eaa7f3SBarry Smith - parentid - indicates the parent of each entry 36142eaa7f3SBarry Smith 36242eaa7f3SBarry Smith Output Parameters: 36342eaa7f3SBarry Smith + Nlevels - the number of levels 36442eaa7f3SBarry Smith . Level - for each node tells its level 36542eaa7f3SBarry Smith . Levelcnts - the number of nodes on each level 36642eaa7f3SBarry Smith . Idbylevel - a list of ids on each of the levels, first level followed by second etc 36742eaa7f3SBarry Smith - Column - for each id tells its column index 36842eaa7f3SBarry Smith 36942eaa7f3SBarry Smith Level: intermediate 37042eaa7f3SBarry Smith 37142eaa7f3SBarry Smith 37242eaa7f3SBarry Smith .seealso: PetscSortReal(), PetscSortIntWithPermutation() 37342eaa7f3SBarry Smith @*/ 3747087cfbeSBarry Smith PetscErrorCode PetscProcessTree(PetscInt n,const PetscBool mask[],const PetscInt parentid[],PetscInt *Nlevels,PetscInt **Level,PetscInt **Levelcnt,PetscInt **Idbylevel,PetscInt **Column) 37542eaa7f3SBarry Smith { 37642eaa7f3SBarry Smith PetscInt i,j,cnt,nmask = 0,nlevels = 0,*level,*levelcnt,levelmax = 0,*workid,*workparentid,tcnt = 0,*idbylevel,*column; 37742eaa7f3SBarry Smith PetscErrorCode ierr; 378ace3abfcSBarry Smith PetscBool done = PETSC_FALSE; 37942eaa7f3SBarry Smith 38042eaa7f3SBarry Smith PetscFunctionBegin; 38142eaa7f3SBarry Smith if (!mask[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mask of 0th location must be set"); 38242eaa7f3SBarry Smith for (i=0; i<n; i++) { 38342eaa7f3SBarry Smith if (mask[i]) continue; 38442eaa7f3SBarry Smith if (parentid[i] == i) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Node labeled as own parent"); 38542eaa7f3SBarry Smith if (parentid[i] && mask[parentid[i]]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Parent is masked"); 38642eaa7f3SBarry Smith } 38742eaa7f3SBarry Smith 38842eaa7f3SBarry Smith 38942eaa7f3SBarry Smith for (i=0; i<n; i++) { 39042eaa7f3SBarry Smith if (!mask[i]) nmask++; 39142eaa7f3SBarry Smith } 39242eaa7f3SBarry Smith 39342eaa7f3SBarry Smith /* determine the level in the tree of each node */ 39442eaa7f3SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&level);CHKERRQ(ierr); 39542eaa7f3SBarry Smith ierr = PetscMemzero(level,n*sizeof(PetscInt));CHKERRQ(ierr); 39642eaa7f3SBarry Smith level[0] = 1; 39742eaa7f3SBarry Smith while (!done) { 39842eaa7f3SBarry Smith done = PETSC_TRUE; 39942eaa7f3SBarry Smith for (i=0; i<n; i++) { 40042eaa7f3SBarry Smith if (mask[i]) continue; 40142eaa7f3SBarry Smith if (!level[i] && level[parentid[i]]) level[i] = level[parentid[i]] + 1; 40242eaa7f3SBarry Smith else if (!level[i]) done = PETSC_FALSE; 40342eaa7f3SBarry Smith } 40442eaa7f3SBarry Smith } 40542eaa7f3SBarry Smith for (i=0; i<n; i++) { 40642eaa7f3SBarry Smith level[i]--; 40742eaa7f3SBarry Smith nlevels = PetscMax(nlevels,level[i]); 40842eaa7f3SBarry Smith } 40942eaa7f3SBarry Smith 41042eaa7f3SBarry Smith /* count the number of nodes on each level and its max */ 41142eaa7f3SBarry Smith ierr = PetscMalloc(nlevels*sizeof(PetscInt),&levelcnt);CHKERRQ(ierr); 41242eaa7f3SBarry Smith ierr = PetscMemzero(levelcnt,nlevels*sizeof(PetscInt));CHKERRQ(ierr); 41342eaa7f3SBarry Smith for (i=0; i<n; i++) { 41442eaa7f3SBarry Smith if (mask[i]) continue; 41542eaa7f3SBarry Smith levelcnt[level[i]-1]++; 41642eaa7f3SBarry Smith } 41742eaa7f3SBarry Smith for (i=0; i<nlevels;i++) { 41842eaa7f3SBarry Smith levelmax = PetscMax(levelmax,levelcnt[i]); 41942eaa7f3SBarry Smith } 42042eaa7f3SBarry Smith 42142eaa7f3SBarry Smith /* for each level sort the ids by the parent id */ 42242eaa7f3SBarry Smith ierr = PetscMalloc2(levelmax,PetscInt,&workid,levelmax,PetscInt,&workparentid);CHKERRQ(ierr); 42342eaa7f3SBarry Smith ierr = PetscMalloc(nmask*sizeof(PetscInt),&idbylevel);CHKERRQ(ierr); 42442eaa7f3SBarry Smith for (j=1; j<=nlevels;j++) { 42542eaa7f3SBarry Smith cnt = 0; 42642eaa7f3SBarry Smith for (i=0; i<n; i++) { 42742eaa7f3SBarry Smith if (mask[i]) continue; 42842eaa7f3SBarry Smith if (level[i] != j) continue; 42942eaa7f3SBarry Smith workid[cnt] = i; 43042eaa7f3SBarry Smith workparentid[cnt++] = parentid[i]; 43142eaa7f3SBarry Smith } 43242eaa7f3SBarry Smith /* PetscIntView(cnt,workparentid,0); 43342eaa7f3SBarry Smith PetscIntView(cnt,workid,0); 43442eaa7f3SBarry Smith ierr = PetscSortIntWithArray(cnt,workparentid,workid);CHKERRQ(ierr); 43542eaa7f3SBarry Smith PetscIntView(cnt,workparentid,0); 43642eaa7f3SBarry Smith PetscIntView(cnt,workid,0);*/ 43742eaa7f3SBarry Smith ierr = PetscMemcpy(idbylevel+tcnt,workid,cnt*sizeof(PetscInt));CHKERRQ(ierr); 43842eaa7f3SBarry Smith tcnt += cnt; 43942eaa7f3SBarry Smith } 44042eaa7f3SBarry Smith if (tcnt != nmask) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent count of unmasked nodes"); 44142eaa7f3SBarry Smith ierr = PetscFree2(workid,workparentid);CHKERRQ(ierr); 44242eaa7f3SBarry Smith 44342eaa7f3SBarry Smith /* for each node list its column */ 44442eaa7f3SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&column);CHKERRQ(ierr); 44542eaa7f3SBarry Smith cnt = 0; 44642eaa7f3SBarry Smith for (j=0; j<nlevels; j++) { 44742eaa7f3SBarry Smith for (i=0; i<levelcnt[j]; i++) { 44842eaa7f3SBarry Smith column[idbylevel[cnt++]] = i; 44942eaa7f3SBarry Smith } 45042eaa7f3SBarry Smith } 45142eaa7f3SBarry Smith 45242eaa7f3SBarry Smith *Nlevels = nlevels; 45342eaa7f3SBarry Smith *Level = level; 45442eaa7f3SBarry Smith *Levelcnt = levelcnt; 45542eaa7f3SBarry Smith *Idbylevel = idbylevel; 45642eaa7f3SBarry Smith *Column = column; 45742eaa7f3SBarry Smith PetscFunctionReturn(0); 45842eaa7f3SBarry Smith } 459