Actual source code: or.c

      2: #include <petsc/private/vecimpl.h>
      3: #include "../src/vec/vec/utils/tagger/impls/andor.h"

      5: /*@C
      6:   VecTaggerOrGetSubs - Get the sub VecTaggers whose union defines the outer VecTagger

      8:   Not collective

     10:   Input Arguments:
     11: . tagger - the VecTagger context

     13:   Output Arguments:
     14: + nsubs - the number of sub VecTaggers
     15: - subs - the sub VecTaggers

     17:   Level: advanced

     19: .seealso: VecTaggerOrSetSubs()
     20: @*/
     21: PetscErrorCode VecTaggerOrGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
     22: {

     26:   VecTaggerGetSubs_AndOr(tagger,nsubs,subs);
     27:   return(0);
     28: }

     30: /*@C
     31:   VecTaggerOrSetSubs - Set the sub VecTaggers whose union defines the outer VecTagger

     33:   Logically collective

     35:   Input Arguments:
     36: + tagger - the VecTagger context
     37: . nsubs - the number of sub VecTaggers
     38: - subs - the sub VecTaggers

     40:   Level: advanced

     42: .seealso: VecTaggerOrSetSubs()
     43: @*/
     44: PetscErrorCode VecTaggerOrSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
     45: {

     49:   VecTaggerSetSubs_AndOr(tagger,nsubs,subs,mode);
     50:   return(0);
     51: }

     53: static PetscErrorCode VecTaggerComputeBoxes_Or(VecTagger tagger,Vec vec,PetscInt *numBoxes,VecTaggerBox **boxes)
     54: {
     55:   PetscInt        i, bs, nsubs, *numSubBoxes, nboxes, total;
     56:   VecTaggerBox    **subBoxes;
     57:   VecTagger       *subs;
     58:   VecTaggerBox    *bxs;
     59:   PetscErrorCode  ierr;

     62:   VecTaggerGetBlockSize(tagger,&bs);
     63:   VecTaggerOrGetSubs(tagger,&nsubs,&subs);
     64:   PetscMalloc2(nsubs,&numSubBoxes,nsubs,&subBoxes);
     65:   for (i = 0, total = 0; i < nsubs; i++) {
     66:     PetscErrorCode ierr2;

     68:     ierr2 = VecTaggerComputeBoxes(subs[i],vec,&numSubBoxes[i],&subBoxes[i]);
     69:     if (ierr2 == PETSC_ERR_SUP) { /* no support, clean up and exit */
     70:       PetscInt j;

     72:       for (j = 0; j < i; j++) {
     73:         PetscFree(subBoxes[j]);
     74:       }
     75:       PetscFree2(numSubBoxes,subBoxes);
     76:       SETERRQ(PetscObjectComm((PetscObject)tagger),PETSC_ERR_SUP,"Sub tagger does not support box computation");
     77:     } else {
     78:       CHKERRQ(ierr2);
     79:     }
     80:     total += numSubBoxes[i];
     81:   }
     82:   PetscMalloc1(bs * total, &bxs);
     83:   for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^2) check to remove subboxes */
     84:     PetscInt j;

     86:     for (j = 0; j < numSubBoxes[i]; j++) {
     87:       PetscInt     k;
     88:       VecTaggerBox *subBox = &subBoxes[i][j*bs];

     90:       for (k = 0; k < nboxes; k++) {
     91:         PetscBool   isSub = PETSC_FALSE;

     93:         VecTaggerBox *prevBox = &bxs[bs * k];
     94:         VecTaggerAndOrIsSubBox_Private(bs,prevBox,subBox,&isSub);
     95:         if (isSub) break;
     96:         VecTaggerAndOrIsSubBox_Private(bs,subBox,prevBox,&isSub);
     97:         if (isSub) {
     98:           PetscInt l;

    100:           for (l = 0; l < bs; l++) prevBox[l] = subBox[l];
    101:           break;
    102:         }
    103:       }
    104:       if (k < nboxes) continue;
    105:       for (k = 0; k < bs; k++) bxs[nboxes * bs + k] = subBox[k];
    106:       nboxes++;
    107:     }
    108:     PetscFree(subBoxes[i]);
    109:   }
    110:   PetscFree2(numSubBoxes,subBoxes);
    111:   *numBoxes = nboxes;
    112:   *boxes = bxs;
    113:   return(0);
    114: }

    116: static PetscErrorCode VecTaggerComputeIS_Or(VecTagger tagger, Vec vec, IS *is)
    117: {
    118:   PetscInt       nsubs, i;
    119:   VecTagger      *subs;
    120:   IS             unionIS;
    121:   PetscErrorCode ierr, ierr2;

    124:   ierr2 = VecTaggerComputeIS_FromBoxes(tagger,vec,is);
    125:   if (ierr2 != PETSC_ERR_SUP) {
    126:     CHKERRQ(ierr2);
    127:     return(0);
    128:   }
    129:   VecTaggerOrGetSubs(tagger,&nsubs,&subs);
    130:   ISCreateGeneral(PetscObjectComm((PetscObject)vec),0,NULL,PETSC_OWN_POINTER,&unionIS);
    131:   for (i = 0; i < nsubs; i++) {
    132:     IS subIS, newUnionIS;

    134:     VecTaggerComputeIS(subs[i],vec,&subIS);
    135:     ISExpand(unionIS,subIS,&newUnionIS);
    136:     ISSort(newUnionIS);
    137:     ISDestroy(&unionIS);
    138:     unionIS = newUnionIS;
    139:     ISDestroy(&subIS);
    140:   }
    141:   *is = unionIS;
    142:   return(0);
    143: }

    145: PETSC_INTERN PetscErrorCode VecTaggerCreate_Or(VecTagger tagger)
    146: {

    150:   VecTaggerCreate_AndOr(tagger);
    151:   tagger->ops->computeboxes = VecTaggerComputeBoxes_Or;
    152:   tagger->ops->computeis        = VecTaggerComputeIS_Or;
    153:   return(0);
    154: }