Actual source code: sliced.c

  1: #define PETSCDM_DLL
  2: 
 3:  #include petscda.h
 4:  #include petscmat.h


  7: typedef struct _SlicedOps *SlicedOps;
  8: struct _SlicedOps {
  9:   PetscErrorCode (*view)(Sliced,PetscViewer);
 10:   PetscErrorCode (*createglobalvector)(Sliced,Vec*);
 11:   PetscErrorCode (*getcoloring)(Sliced,ISColoringType,ISColoring*);
 12:   PetscErrorCode (*getmatrix)(Sliced,MatType,Mat*);
 13:   PetscErrorCode (*getinterpolation)(Sliced,Sliced,Mat*,Vec*);
 14:   PetscErrorCode (*refine)(Sliced,MPI_Comm,Sliced*);
 15: };

 17: struct _p_Sliced {
 18:   PETSCHEADER(struct _SlicedOps);
 19:   Vec      globalvector;
 20:   PetscInt bs,n,N,Nghosts,*ghosts;
 21:   PetscInt d_nz,o_nz,*d_nnz,*o_nnz;
 22: };

 26: /*@C
 27:     SlicedGetMatrix - Creates a matrix with the correct parallel layout required for 
 28:       computing the Jacobian on a function defined using the informatin in Sliced.

 30:     Collective on Sliced

 32:     Input Parameter:
 33: +   slice - the slice object
 34: -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
 35:             or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).

 37:     Output Parameters:
 38: .   J  - matrix with the correct nonzero preallocation
 39:         (obviously without the correct Jacobian values)

 41:     Level: advanced

 43:     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you 
 44:        do not need to do it yourself.

 46: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DASetBlockFills()

 48: @*/
 49: PetscErrorCode  SlicedGetMatrix(Sliced slice, MatType mtype,Mat *J)
 50: {
 51:   PetscErrorCode         ierr;
 52:   PetscInt               *globals,rstart,i;
 53:   ISLocalToGlobalMapping lmap;

 56:   MatCreate(slice->comm,J);
 57:   MatSetSizes(*J,slice->n,slice->n,PETSC_DETERMINE,PETSC_DETERMINE);
 58:   MatSetType(*J,mtype);
 59:   MatSetBlockSize(*J,slice->bs);
 60:   MatSeqAIJSetPreallocation(*J,slice->d_nz,slice->d_nnz);
 61:   MatMPIAIJSetPreallocation(*J,slice->d_nz,slice->d_nnz,slice->o_nz,slice->o_nnz);
 62:   MatSeqBAIJSetPreallocation(*J,slice->bs,slice->d_nz,slice->d_nnz);
 63:   MatMPIBAIJSetPreallocation(*J,slice->bs,slice->d_nz,slice->d_nnz,slice->o_nz,slice->o_nnz);

 65:   PetscMalloc((slice->n+slice->Nghosts+1)*sizeof(PetscInt),&globals);
 66:   MatGetOwnershipRange(*J,&rstart,PETSC_NULL);
 67:   for (i=0; i<slice->n; i++) {
 68:     globals[i] = rstart + i;
 69:   }
 70:   PetscMemcpy(globals+slice->n,slice->ghosts,slice->Nghosts*sizeof(PetscInt));
 71:   ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,slice->n+slice->Nghosts,globals,&lmap);
 72:   PetscFree(globals);
 73:   MatSetLocalToGlobalMapping(*J,lmap);
 74:   ISLocalToGlobalMappingDestroy(lmap);
 75:   return(0);
 76: }

 80: /*@C
 81:     SlicedSetGhosts - Sets the global indices of other processes elements that will
 82:       be ghosts on this process

 84:     Not Collective

 86:     Input Parameters:
 87: +    slice - the Sliced object
 88: .    bs - block size
 89: .    nlocal - number of local (non-ghost) entries
 90: .    Nghosts - number of ghosts on this process
 91: -    ghosts - indices of all the ghost points

 93:     Level: advanced

 95: .seealso SlicedDestroy(), SlicedCreateGlobalVector(), SlicedGetGlobalIndices()

 97: @*/
 98: PetscErrorCode  SlicedSetGhosts(Sliced slice,PetscInt bs,PetscInt nlocal,PetscInt Nghosts,const PetscInt ghosts[])
 99: {

104:   PetscFree(slice->ghosts);
105:   PetscMalloc((1+Nghosts)*sizeof(PetscInt),&slice->ghosts);
106:   PetscMemcpy(slice->ghosts,ghosts,Nghosts*sizeof(PetscInt));
107:   slice->bs      = bs;
108:   slice->n       = nlocal;
109:   slice->Nghosts = Nghosts;
110:   return(0);
111: }

115: /*@C
116:     SlicedSetPreallocation - sets the matrix memory preallocation for matrices computed by Sliced

118:     Not Collective

120:     Input Parameters:
121: +    slice - the Sliced object
122: .    d_nz - maximum number of nonzeros in any row of diagonal block
123: .    d_nnz - number of nonzeros in each row of diagonal block
124: .    o_nz - maximum number of nonzeros in any row of off-diagonal block
125: .    o_nnz - number of nonzeros in each row of off-diagonal block


128:     Level: advanced

130: .seealso SlicedDestroy(), SlicedCreateGlobalVector(), SlicedGetGlobalIndices(), MatMPIAIJSetPreallocation(),
131:          MatMPIBAIJSetPreallocation()

133: @*/
134: PetscErrorCode  SlicedSetPreallocation(Sliced slice,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[])
135: {
138:   slice->d_nz  = d_nz;
139:   slice->d_nnz = (PetscInt*)d_nnz;
140:   slice->o_nz  = o_nz;
141:   slice->o_nnz = (PetscInt*)o_nnz;
142:   return(0);
143: }

147: /*@C
148:     SlicedCreate - Creates a DM object, used to manage data for a unstructured problem

150:     Collective on MPI_Comm

152:     Input Parameter:
153: .   comm - the processors that will share the global vector

155:     Output Parameters:
156: .   slice - the slice object

158:     Level: advanced

160: .seealso SlicedDestroy(), SlicedCreateGlobalVector(), SlicedGetGlobalIndices()

162: @*/
163: PetscErrorCode  SlicedCreate(MPI_Comm comm,Sliced *slice)
164: {
166:   Sliced         p;

170:   *slice = PETSC_NULL;
171: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
172:   DMInitializePackage(PETSC_NULL);
173: #endif

175:   PetscHeaderCreate(p,_p_Sliced,struct _SlicedOps,DA_COOKIE,0,"Sliced",comm,SlicedDestroy,0);
176:   p->ops->createglobalvector = SlicedCreateGlobalVector;
177:   p->ops->getmatrix          = SlicedGetMatrix;
178:   *slice = p;
179:   return(0);
180: }

184: /*@C
185:     SlicedDestroy - Destroys a vector slice.

187:     Collective on Sliced

189:     Input Parameter:
190: .   slice - the slice object

192:     Level: advanced

194: .seealso SlicedCreate(), SlicedCreateGlobalVector(), SlicedGetGlobalIndices()

196: @*/
197: PetscErrorCode  SlicedDestroy(Sliced slice)
198: {
199:   PetscErrorCode     ierr;

202:   if (--slice->refct > 0) return(0);
203:   if (slice->globalvector) {VecDestroy(slice->globalvector);}
204:   PetscHeaderDestroy(slice);
205:   return(0);
206: }

210: /*@C
211:     SlicedCreateGlobalVector - Creates a vector of the correct size to be gathered into 
212:         by the slice.

214:     Collective on Sliced

216:     Input Parameter:
217: .    slice - the slice object

219:     Output Parameters:
220: .   gvec - the global vector

222:     Level: advanced

224:     Notes: Once this has been created you cannot add additional arrays or vectors to be packed.

226: .seealso SlicedDestroy(), SlicedCreate(), SlicedGetGlobalIndices()

228: @*/
229: PetscErrorCode  SlicedCreateGlobalVector(Sliced slice,Vec *gvec)
230: {
231:   PetscErrorCode     ierr;


235:   if (slice->globalvector) {
236:     VecDuplicate(slice->globalvector,gvec);
237:   } else {
238:     VecCreateGhostBlock(slice->comm,slice->bs,slice->n,PETSC_DETERMINE,slice->Nghosts,slice->ghosts,&slice->globalvector);
239:     *gvec = slice->globalvector;
240:     PetscObjectReference((PetscObject)*gvec);
241:   }
242:   return(0);
243: }

247: /*@C
248:     SlicedGetGlobalIndices - Gets the global indices for all the local entries

250:     Collective on Sliced

252:     Input Parameter:
253: .    slice - the slice object

255:     Output Parameters:
256: .    idx - the individual indices for each packed vector/array
257:  
258:     Level: advanced

260:     Notes:
261:        The idx parameters should be freed by the calling routine with PetscFree()

263: .seealso SlicedDestroy(), SlicedCreateGlobalVector(), SlicedCreate()

265: @*/
266: PetscErrorCode  SlicedGetGlobalIndices(Sliced slice,PetscInt *idx[])
267: {
268:   return(0);
269: }