Exemplo n.º 1
0
/** Get coordinates for every node in closure (every subelement vertex)
 *
 * @note This function cannot be implemented for all \a dFS types.  For most purposes, users should
 *       \a dFSGetGeometryVectorExpanded and evaluate (element by element) on the nodes of their choice
 *       (with a self-quadrature).
 *
 * @param fs Function space
 * @param inx the new vector with block size 3 and the same number of blocks as the closure vector
 **/
dErr dFSGetNodalCoordinatesGlobal(dFS fs,Vec *inx)
{
    dErr    err;
    Vec     Expanded,Ones,X,Count,Xclosure,Countclosure;
    dFS     fs3;

    dFunctionBegin;
    dValidHeader(fs,DM_CLASSID,1);
    dValidPointer(inx,2);
    *inx = 0;

    err = dFSGetNodalCoordinateFS(fs,&fs3);
    dCHK(err);
    err = dFSGetNodalCoordinatesExpanded(fs,&Expanded);
    dCHK(err);
    if (!fs->nodalcoord.global) {
        err = dFSCreateGlobalVector(fs3,&fs->nodalcoord.global);
        dCHK(err);
    }
    X = fs->nodalcoord.global;

    /* Count the number of occurances of each node in the closure. */
    err = VecDuplicate(Expanded,&Ones);
    dCHK(err);
    err = VecDuplicate(X,&Count);
    dCHK(err);

    err = VecDohpZeroEntries(Count);
    dCHK(err);
    err = VecSet(Ones,1.);
    dCHK(err);
    err = dFSExpandedToGlobal(fs3,Ones,Count,dFS_INHOMOGENEOUS,ADD_VALUES);
    dCHK(err);
    err = VecDestroy(&Ones);
    dCHK(err);

    err = VecDohpZeroEntries(X);
    dCHK(err);
    err = dFSExpandedToGlobal(fs3,Expanded,X,dFS_INHOMOGENEOUS,ADD_VALUES);
    dCHK(err);

    err = VecDohpGetClosure(X,&Xclosure);
    dCHK(err);
    err = VecDohpGetClosure(Count,&Countclosure);
    dCHK(err);
    err = VecPointwiseDivide(Xclosure,Xclosure,Countclosure);
    dCHK(err);
    err = VecDohpRestoreClosure(X,&Xclosure);
    dCHK(err);
    err = VecDohpRestoreClosure(Count,&Countclosure);
    dCHK(err);

    err = VecDestroy(&Count);
    dCHK(err);
    *inx = X;
    dFunctionReturn(0);
}
Exemplo n.º 2
0
Arquivo: vecd.c Projeto: xyuan/dohp
/** Create a cache for Dirichlet part of closure vector, and scatter from global closure to Dirichlet cache.

@arg[in] gvec Global vector
@arg[out] dcache New vector to hold the Dirichlet values
@arg[out] dscat Scatter from global closure to \a dcache

@note This could be local but it doesn't cost anything to make it global.
**/
dErr VecDohpCreateDirichletCache(Vec gvec,Vec *dcache,VecScatter *dscat)
{
  MPI_Comm comm;
  dErr     err;
  dBool    isdohp;
  IS       from;
  Vec      gc;
  dInt     n,nc,crstart;

  dFunctionBegin;
  dValidHeader(gvec,VEC_CLASSID,1);
  dValidPointer(dcache,2);
  dValidPointer(dscat,3);
  err = PetscTypeCompare((PetscObject)gvec,VECDOHP,&isdohp);dCHK(err);
  if (!isdohp) dERROR(PETSC_COMM_SELF,PETSC_ERR_SUP,"Vec type %s",((PetscObject)gvec)->type_name);
  err = PetscObjectGetComm((PetscObject)gvec,&comm);dCHK(err);
  err = VecGetLocalSize(gvec,&n);dCHK(err);
  err = VecDohpGetClosure(gvec,&gc);dCHK(err);
  err = VecGetLocalSize(gc,&nc);dCHK(err);
  err = VecGetOwnershipRange(gc,&crstart,NULL);dCHK(err);
  err = VecCreateMPI(comm,nc-n,PETSC_DECIDE,dcache);dCHK(err);
  err = ISCreateStride(comm,nc-n,crstart+n,1,&from);dCHK(err);
  err = VecScatterCreate(gc,from,*dcache,NULL,dscat);dCHK(err);
  err = VecDohpRestoreClosure(gvec,&gc);dCHK(err);
  err = ISDestroy(&from);dCHK(err);
  /* \todo deal with rotations */
  dFunctionReturn(0);
}
Exemplo n.º 3
0
Arquivo: vecd.c Projeto: xyuan/dohp
dErr VecDohpZeroEntries(Vec v)
{
  dErr err;
  dBool  isdohp;
  Vec c;

  dFunctionBegin;
  dValidHeader(v,VEC_CLASSID,1);
  err = PetscTypeCompare((dObject)v,VECDOHP,&isdohp);dCHK(err);
  if (!isdohp) dERROR(PETSC_COMM_SELF,PETSC_ERR_SUP,"Vector type %s",((dObject)v)->type_name);
  err = VecDohpGetClosure(v,&c);dCHK(err);
  err = VecZeroEntries(c);dCHK(err);
  err = VecDohpRestoreClosure(v,&c);dCHK(err);
  dFunctionReturn(0);
}
Exemplo n.º 4
0
dErr dFSSubElementMeshView(dFS fs,dViewer view)
{
    dErr err;
    dInt nelem,nverts,nconn,*suboff,*subind,n,bs;
    dEntTopology *subtopo;
    Vec X,Xc;
    const dReal *x;
    const char *name;

    dFunctionBegin;
    err = dFSGetSubElementMeshSize(fs,&nelem,&nverts,&nconn);
    dCHK(err);
    dASSERT(nconn == 8*nelem);    /* Assume Hex */
    err = dMallocA3(nelem,&subtopo,nelem+1,&suboff,nconn,&subind);
    dCHK(err);
    err = dFSGetSubElementMesh(fs,nelem,nconn,subtopo,suboff,subind);
    dCHK(err);
    err = PetscObjectGetName((dObject)fs,&name);
    dCHK(err);
    err = PetscViewerASCIIPrintf(view,"SubElementMesh name=%s nelem=%D nverts=%D\n",name,nelem,nverts);
    dCHK(err);
    err = dIntTableView(nelem,8,subind,view,"subconn");
    dCHK(err);
    err = dFree3(subtopo,suboff,subind);
    dCHK(err);

    err = dFSGetNodalCoordinatesGlobal(fs,&X);
    dCHK(err);
    err = VecDohpGetClosure(X,&Xc);
    dCHK(err);
    err = VecGetLocalSize(Xc,&n);
    dCHK(err);
    err = VecGetBlockSize(Xc,&bs);
    dCHK(err);
    err = VecGetArrayRead(Xc,&x);
    dCHK(err);
    err = dRealTableView(n/bs,bs,x,view,"coords");
    dCHK(err);
    err = VecRestoreArrayRead(Xc,&x);
    dCHK(err);
    err = VecDohpRestoreClosure(X,&Xc);
    dCHK(err);
    dFunctionReturn(0);
}
Exemplo n.º 5
0
Arquivo: vecd.c Projeto: xyuan/dohp
static dErr VecDuplicate_Dohp(Vec x,Vec *iny)
{
  Vec      y,xc,yc;
  Vec_MPI *ympi;
  dScalar *a;
  dErr     err;

  dFunctionBegin;
  dValidHeader(x,VEC_CLASSID,1);
  dValidPointer(iny,2);
  *iny = 0;
  err = VecDohpGetClosure(x,&xc);dCHK(err);
  err = VecDuplicate(xc,&yc);dCHK(err);
  err = VecDohpRestoreClosure(x,&xc);dCHK(err);

  /* The rest is mostly the same as VecDuplicate_MPI, but we can't call that because it allocates memory.
  * Unfortunately, this is fragile if the VecMPI implementation changes.  I think this part of PETSc is quite stable and
  * I will be sufficiently involved to notice changes here. Famous last words. */
  err = VecCreate(((dObject)x)->comm,&y);dCHK(err);

  err = PetscLayoutReference(x->map,&y->map);dCHK(err);

  err = VecGetArray(yc,&a);dCHK(err);
  err = VecCreate_MPI_Private(y,PETSC_FALSE,0,a);dCHK(err);
  err = VecRestoreArray(yc,&a);dCHK(err);
  ympi = y->data;
  err = dMemcpy(y->ops,x->ops,sizeof(struct _VecOps));dCHK(err);

  ympi->localrep = yc;             /* subverting .localrep to mean closed form */

  y->stash.donotstash   = x->stash.donotstash;
  y->stash.ignorenegidx = x->stash.ignorenegidx;

  err = PetscOListDuplicate(((dObject)x)->olist,&((dObject)y)->olist);dCHK(err);
  err = PetscFListDuplicate(((dObject)x)->qlist,&((dObject)y)->qlist);dCHK(err);
  y->map->bs   = x->map->bs;
  y->bstash.bs = x->bstash.bs;

  err = PetscObjectChangeTypeName((dObject)y,VECDOHP);dCHK(err);
  *iny = y;
  dFunctionReturn(0);
}
Exemplo n.º 6
0
/** Apply rotation to global vector
*
* @note does nothing if rotation is NULL
**/
dErr dFSRotationApply(dFSRotation rot,Vec g,dFSRotateMode rmode,dFSHomogeneousMode hmode)
{
  dErr err;
  Vec  gc,lf;

  dFunctionBegin;
  if (!rot) dFunctionReturn(0);
  dValidHeader(rot,dFSROT_CLASSID,1);
  dValidHeader(g,VEC_CLASSID,2);
  if (rot->ops->apply) {
    err = rot->ops->apply(rot,g,rmode,hmode);dCHK(err);
  } else {
    err = VecDohpGetClosure(g,&gc);dCHK(err);
    err = VecGhostGetLocalForm(gc,&lf);dCHK(err);
    err = dFSRotationApplyLocal(rot,lf,rmode,hmode);dCHK(err); /* \todo only rotate the global portion */
    err = VecGhostRestoreLocalForm(gc,&lf);dCHK(err);
    err = VecDohpRestoreClosure(g,&gc);dCHK(err);
  }
  dFunctionReturn(0);
}