Пример #1
0
/*
    Given a DA generates a VecScatter context that will deliver a slice
  of the global vector to each processor. In this example, each processor
  receives the values i=*, j=*, k=rank, i.e. one z plane.

  Note: This code is written assuming only one degree of freedom per node.
  For multiple degrees of freedom per node use ISCreateBlock()
  instead of ISCreateGeneral().
*/
PetscErrorCode GenerateSliceScatter(DA da,VecScatter *scatter,Vec *vslice)
{
  AO             ao;
  PetscInt       M,N,P,nslice,*sliceindices,count,i,j;
  PetscMPIInt    rank;
  PetscErrorCode ierr;
  MPI_Comm       comm;
  Vec            vglobal;
  IS             isfrom,isto;

  ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr);
  ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);

  ierr = DAGetAO(da,&ao);CHKERRQ(ierr);
  ierr = DAGetInfo(da,0,&M,&N,&P,0,0,0,0,0,0,0);CHKERRQ(ierr);

  /* 
     nslice is number of degrees of freedom in this processors slice
   if there are more processors then z plans the extra processors get 0
   elements in their slice.
  */
  if (rank < P) {nslice = M*N;} else nslice = 0;

  /* 
     Generate the local vector to hold this processors slice
  */
  ierr = VecCreateSeq(PETSC_COMM_SELF,nslice,vslice);CHKERRQ(ierr);
  ierr = DACreateGlobalVector(da,&vglobal);CHKERRQ(ierr);

  /*
       Generate the indices for the slice in the "natural" global ordering
     Note: this is just an example, one could select any subset of nodes 
    on each processor. Just list them in the global natural ordering.

  */
  ierr = PetscMalloc((nslice+1)*sizeof(PetscInt),&sliceindices);CHKERRQ(ierr);
  count = 0;
  if (rank < P) {
    for (j=0; j<N; j++) {
      for (i=0; i<M; i++) {
         sliceindices[count++] = rank*M*N + j*M + i;
      }
    }
  }
  /*
      Convert the indices to the "PETSc" global ordering
  */
  ierr = AOApplicationToPetsc(ao,nslice,sliceindices);CHKERRQ(ierr); 
  
  /* Create the "from" and "to" index set */
  /* This is to scatter from the global vector */
  ierr = ISCreateGeneral(PETSC_COMM_SELF,nslice,sliceindices,&isfrom);CHKERRQ(ierr);
  /* This is to gather into the local vector */
  ierr = ISCreateStride(PETSC_COMM_SELF,nslice,0,1,&isto);CHKERRQ(ierr);
  ierr = VecScatterCreate(vglobal,isfrom,*vslice,isto,scatter);CHKERRQ(ierr);
  ierr = ISDestroy(isfrom);CHKERRQ(ierr); 
  ierr = ISDestroy(isto);CHKERRQ(ierr);
  ierr = PetscFree(sliceindices);CHKERRQ(ierr);
  return 0;
}
Пример #2
0
EXTERN_C_END

#undef __FUNCT__
#define __FUNCT__ "DAMapCoordsToPeriodicDomain"
/* -----------------------------------------------------------------------------
   Checks for periodicity of a DA and Maps points outside of a domain back onto the domain
   using appropriate periodicity. At the moment assumes only a 2-D DA.
   ----------------------------------------------------------------------------------------*/
PetscErrorCode DAMapCoordsToPeriodicDomain(DA da, PetscScalar *x, PetscScalar *y)
{
  DAPeriodicType periodic_type;
  PetscInt       dim, gx, gy;
  PetscErrorCode ierr;

  PetscFunctionBegin;
  ierr = DAGetInfo(da, &dim, &gx, &gy, 0, 0, 0, 0, 0, 0, &periodic_type, 0);

  if ( periodic_type == DA_NONPERIODIC ) {
    ierr = 0;
  } else {
    if (periodic_type==DA_XPERIODIC || periodic_type==DA_XYPERIODIC) {
      while (*x >= ( PetscScalar ) gx ) { *x -= ( PetscScalar ) gx; }
      while (*x < 0.0 )                 { *x += ( PetscScalar ) gx; }
    }
    if (periodic_type==DA_YPERIODIC || periodic_type==DA_XYPERIODIC) {
      while (*y >= ( PetscScalar ) gy ) { *y -= ( PetscScalar ) gy; }
      while (*y < 0.0 )                 { *y += ( PetscScalar ) gy; }
    }
  }
    
  PetscFunctionReturn(ierr);
}
Пример #3
0
int main(int argc,char **argv)
{
  DMMG           *dmmg;          /* multilevel grid structure */
  AppCtx         user;                /* user-defined work context */
  PetscInt       mx,my,its;
  PetscErrorCode ierr;
  MPI_Comm       comm;
  SNES           snes;
  DA             da2;

  PetscInitialize(&argc,&argv,(char *)0,help);
  comm = PETSC_COMM_WORLD;

  /* Problem parameters (velocity of lid, prandtl, and grashof numbers) */
  ierr = PetscOptionsGetReal(PETSC_NULL,"-lidvelocity",&user.lidvelocity,PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscOptionsGetReal(PETSC_NULL,"-prandtl",&user.prandtl,PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscOptionsGetReal(PETSC_NULL,"-grashof",&user.grashof,PETSC_NULL);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Create user context, set problem data, create vector data structures.
     Also, compute the initial guess.
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Setup Physics 2: 
        - Lap(T) + PR*Div([U*T,V*T]) = 0        
        where U and V are given by the given x.u and x.v
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,&da2);CHKERRQ(ierr);
  ierr = DASetFieldName(da2,0,"temperature");CHKERRQ(ierr);

  /* Create the solver object and attach the grid/physics info */
  ierr = DMMGCreate(comm,1,&user,&dmmg);CHKERRQ(ierr);
  ierr = DMMGSetDM(dmmg,(DM)da2);CHKERRQ(ierr);
  ierr = DMMGSetISColoringType(dmmg,IS_COLORING_GLOBAL);CHKERRQ(ierr);

  ierr = DMMGSetInitialGuess(dmmg,FormInitialGuess);CHKERRQ(ierr);
  ierr = DMMGSetSNES(dmmg,FormFunction,0);CHKERRQ(ierr);
  ierr = DMMGSetFromOptions(dmmg);CHKERRQ(ierr);

  ierr = DAGetInfo(da2,PETSC_NULL,&mx,&my,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  user.lidvelocity = 1.0/(mx*my);
  user.prandtl     = 1.0;
  user.grashof     = 1.0;

  /* Solve the nonlinear system */
  ierr = DMMGSolve(dmmg);CHKERRQ(ierr); 
  snes = DMMGGetSNES(dmmg);
  ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
  ierr = PetscPrintf(comm,"Physics 2: Number of Newton iterations = %D\n\n", its);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Free spaces 
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DADestroy(da2);CHKERRQ(ierr);
  ierr = DMMGDestroy(dmmg);CHKERRQ(ierr);
  ierr = PetscFinalize();CHKERRQ(ierr);
  return 0;
}
Пример #4
0
PetscErrorCode ComputeRHS(DA da,Vec b)
{
  PetscErrorCode ierr;
  PetscInt       mx,my,mz;
  PetscScalar    h;

  PetscFunctionBegin;
  ierr = DAGetInfo(da,0,&mx,&my,&mz,0,0,0,0,0,0,0);CHKERRQ(ierr);
  h    = 1.0/((mx-1)*(my-1)*(mz-1));
  ierr = VecSet(b,h);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Пример #5
0
void PETSC_STDCALL dagetownershipranges_(DA *da,PetscInt lx[],PetscInt ly[],PetscInt lz[],PetscErrorCode *ierr)
{
  const PetscInt *gx,*gy,*gz;
  PetscInt       M,N,P,i;
  
  CHKFORTRANNULLINTEGER(lx);
  CHKFORTRANNULLINTEGER(ly);
  CHKFORTRANNULLINTEGER(lz);
  *ierr = DAGetInfo(*da,0,0,0,0,&M,&N,&P,0,0,0,0);if (*ierr) return;
  *ierr = DAGetOwnershipRanges(*da,&gx,&gy,&gz);if (*ierr) return;
  if (lx) {for (i=0; i<M; i++) {lx[i] = gx[i];}}
  if (ly) {for (i=0; i<N; i++) {ly[i] = gy[i];}}
  if (lz) {for (i=0; i<P; i++) {lz[i] = gz[i];}}
}
Пример #6
0
PetscErrorCode ComputeFunction(SNES snes,Vec x,Vec f,void *ctx) {
  PetscInt i,Mx,xs,xm; PetscScalar *xx,*ff,hx; DA da = (DA) ctx; Vec xlocal;
  DAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
  hx     = 1.0/(PetscReal)(Mx-1);
  DAGetLocalVector(da,&xlocal);DAGlobalToLocalBegin(da,x,INSERT_VALUES,xlocal);  DAGlobalToLocalEnd(da,x,INSERT_VALUES,xlocal);
  DAVecGetArray(da,xlocal,&xx); DAVecGetArray(da,f,&ff);
  DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);

  for (i=xs; i<xs+xm; i++) {
    if (i == 0 || i == Mx-1) ff[i] = xx[i]/hx; 
    else  ff[i] =  (2.0*xx[i] - xx[i-1] - xx[i+1])/hx - hx*PetscExpScalar(xx[i]); 
  }
  DAVecRestoreArray(da,xlocal,&xx); DARestoreLocalVector(da,&xlocal);DAVecRestoreArray(da,f,&ff);
  return 0;}
Пример #7
0
/* 
   FormInitialGuessLocal - Forms initial approximation for this process

   Input Parameters:
     user - user-defined application context
     X    - vector (DA local vector)

   Output Parameter:
     X - vector with the local values set
 */
PetscErrorCode FormInitialGuessLocal(DMMG dmmg,Vec X)
{
  AppCtx         *user = (AppCtx*)dmmg->user;
  DA             da = (DA)dmmg->dm;
  PetscInt       i,j,mx,xs,ys,xm,ym;
  PetscErrorCode ierr;
  PetscReal      grashof,dx;
  Field          **x;

  grashof = user->grashof;
  ierr = DAGetInfo(da,0,&mx,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  dx  = 1.0/(mx-1);

  /*
     Get local grid boundaries (for 2-dimensional DA):
       xs, ys   - starting grid indices (no ghost points)
       xm, ym   - widths of local grid (no ghost points)
  */
  ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr);

  /*
     Get a pointer to vector data.
       - For default PETSc vectors, VecGetArray() returns a pointer to
         the data array.  Otherwise, the routine is implementation dependent.
       - You MUST call VecResetArraystoreArray() when you no longer need access to
         the array.
  */
  ierr = DAVecGetArray(da,X,&x);CHKERRQ(ierr);

  /*
     Compute initial guess over the locally owned part of the grid
     Initial condition is motionless fluid and equilibrium temperature
     U = V = Omega = 0.0; Temp[x_i, y_j] = x_i;
  */
  for (j=ys; j<ys+ym; j++) {
    for (i=xs; i<xs+xm; i++) {
      x[j][i].u     = 0.0;
      x[j][i].v     = 0.0;
      x[j][i].omega = 0.0;
      x[j][i].temp  = (grashof>0)*i*dx;  
    }
  }

  /* Restore vector */
  ierr = DAVecRestoreArray(da,X,&x);CHKERRQ(ierr);
  return 0;
}
Пример #8
0
void PETSC_STDCALL dasetlocalfunction_(DA *da,void (PETSC_STDCALL *func)(DALocalInfo*,void*,void*,void*,PetscErrorCode*),PetscErrorCode *ierr)
{
  PetscInt dim;

  PetscObjectAllocateFortranPointers(*da,6);
  *ierr = DAGetInfo(*da,&dim,0,0,0,0,0,0,0,0,0,0); if (*ierr) return;
  if (dim == 2) {
    ((PetscObject)*da)->fortran_func_pointers[4] = (PetscVoidFunction)func;
    *ierr = DASetLocalFunction(*da,(DALocalFunction1)ourlf2d);
  } else if (dim == 3) {
    ((PetscObject)*da)->fortran_func_pointers[5] = (PetscVoidFunction)func;
    *ierr = DASetLocalFunction(*da,(DALocalFunction1)ourlf3d);
  } else if (dim == 1) {
    ((PetscObject)*da)->fortran_func_pointers[3] = (PetscVoidFunction)func;
    *ierr = DASetLocalFunction(*da,(DALocalFunction1)ourlf1d);
  } else *ierr = 1;
}
Пример #9
0
void PETSC_STDCALL dasetlocaljacobian_(DA *da,void (PETSC_STDCALL *jac)(DALocalInfo*,void*,void*,void*,PetscErrorCode*),PetscErrorCode *ierr)
{
  PetscInt dim;

  PetscObjectAllocateFortranPointers(*da,6);
  *ierr = DAGetInfo(*da,&dim,0,0,0,0,0,0,0,0,0,0); if (*ierr) return;
  if (dim == 2) {
    ((PetscObject)*da)->fortran_func_pointers[1] = (PetscVoidFunction)jac;
    *ierr = DASetLocalJacobian(*da,(DALocalFunction1)ourlj2d);
  } else if (dim == 3) {
    ((PetscObject)*da)->fortran_func_pointers[2] = (PetscVoidFunction)jac;
    *ierr = DASetLocalJacobian(*da,(DALocalFunction1)ourlj3d);
  } else if (dim == 1) {
    ((PetscObject)*da)->fortran_func_pointers[0] = (PetscVoidFunction)jac;
    *ierr = DASetLocalJacobian(*da,(DALocalFunction1)ourlj1d);
  } else *ierr = 1;
}
Пример #10
0
PetscErrorCode ComputeJacobian(SNES snes,Vec x,Mat *J,Mat *B,MatStructure *flag,void *ctx){
  DA da = (DA) ctx; PetscInt i,Mx,xm,xs; PetscScalar hx,*xx; Vec xlocal;
  DAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
  hx = 1.0/(PetscReal)(Mx-1);
  DAGetLocalVector(da,&xlocal);DAGlobalToLocalBegin(da,x,INSERT_VALUES,xlocal);  DAGlobalToLocalEnd(da,x,INSERT_VALUES,xlocal);
  DAVecGetArray(da,xlocal,&xx);
  DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);

  for (i=xs; i<xs+xm; i++) {
    if (i == 0 || i == Mx-1) { MatSetValue(*J,i,i,1.0/hx,INSERT_VALUES);}
    else {
      MatSetValue(*J,i,i-1,-1.0/hx,INSERT_VALUES);
      MatSetValue(*J,i,i,2.0/hx - hx*PetscExpScalar(xx[i]),INSERT_VALUES);
      MatSetValue(*J,i,i+1,-1.0/hx,INSERT_VALUES);
    }
  }
  MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);  *flag = SAME_NONZERO_PATTERN;
  DAVecRestoreArray(da,xlocal,&xx);DARestoreLocalVector(da,&xlocal);
  return 0;}
Пример #11
0
PetscErrorCode CharacteristicSetUp_DA(Characteristic c)
{
  PetscMPIInt    blockLen[2];
  MPI_Aint       indices[2];
  MPI_Datatype   oldtypes[2]; 
  PetscInt       dim, numValues;
  PetscErrorCode ierr;

  ierr = DAGetInfo(c->velocityDA, &dim, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);CHKERRQ(ierr);
  if (c->structured) {
    c->numIds = dim;
  } else {
    c->numIds = 3;
  }
  if (c->numFieldComp > MAX_COMPONENTS) {
    SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "The maximum number of fields allowed is %d, you have %d. You can recompile after increasing MAX_COMPONENTS.", MAX_COMPONENTS, c->numFieldComp);
  }
  numValues = 4 + MAX_COMPONENTS;

  /* Create new MPI datatype for communication of characteristic point structs */
  blockLen[0] = 1+c->numIds; indices[0] = 0;                              oldtypes[0] = MPIU_INT;
  blockLen[1] = numValues;   indices[1] = (1+c->numIds)*sizeof(PetscInt); oldtypes[1] = MPIU_SCALAR;
  ierr = MPI_Type_struct(2, blockLen, indices, oldtypes, &c->itemType);CHKERRQ(ierr);
  ierr = MPI_Type_commit(&c->itemType);CHKERRQ(ierr);

  /* Initialize the local queue for char foot values */
  ierr = VecGetLocalSize(c->velocity, &c->queueMax);CHKERRQ(ierr);
  ierr = PetscMalloc(c->queueMax * sizeof(CharacteristicPointDA2D), &c->queue);CHKERRQ(ierr);
  c->queueSize = 0;

  /* Allocate communication structures */
  if (c->numNeighbors <= 0) {
    SETERRQ1(PETSC_ERR_ARG_WRONGSTATE, "Invalid number of neighbors %d. Call CharactersiticSetNeighbors() before setup.", c->numNeighbors);
  }
  ierr = PetscMalloc(c->numNeighbors * sizeof(PetscInt), &c->needCount);CHKERRQ(ierr);
  ierr = PetscMalloc(c->numNeighbors * sizeof(PetscInt), &c->localOffsets);CHKERRQ(ierr);
  ierr = PetscMalloc(c->numNeighbors * sizeof(PetscInt), &c->fillCount);CHKERRQ(ierr);
  ierr = PetscMalloc(c->numNeighbors * sizeof(PetscInt), &c->remoteOffsets);CHKERRQ(ierr);
  ierr = PetscMalloc((c->numNeighbors-1) * sizeof(MPI_Request), &c->request);CHKERRQ(ierr);
  ierr = PetscMalloc((c->numNeighbors-1) * sizeof(MPI_Status),  &c->status);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Пример #12
0
PetscErrorCode doit(DA da,Vec global)
{
  PetscErrorCode ierr;
  PetscInt       i,j,k,M,N,dof;

  ierr = DAGetInfo(da,0,&M,&N,0,0,0,0,&dof,0,0,0);CHKERRQ(ierr);
  {
    struct {PetscScalar inside[dof];} **mystruct;
    ierr = DAVecGetArray(da,global,(void*) &mystruct);
    for ( i=0; i<N; i++) {
      for ( j=0; j<M; j++) {
	for ( k=0; k<dof; k++) {
	  ierr = PetscPrintf(PETSC_COMM_WORLD,"%d %d %G\n",i,j,mystruct[i][j].inside[0]);CHKERRQ(ierr);
	  mystruct[i][j].inside[1] = 2.1;
	}
      }
    }
    ierr = DAVecRestoreArray(da,global,(void*) &mystruct);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}
Пример #13
0
/* Form initial guess for Physic 1 */
PetscErrorCode FormInitialGuessLocal1(DMMG dmmg,Vec X)
{
  AppCtx         *user = (AppCtx*)dmmg->user;
  DA             da = (DA)dmmg->dm;
  PetscInt       i,j,mx,xs,ys,xm,ym;
  PetscErrorCode ierr;
  Field1         **x;

  ierr = DAGetInfo(da,0,&mx,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr);

  ierr = DAVecGetArray(da,X,&x);CHKERRQ(ierr);
  for (j=ys; j<ys+ym; j++) {
    for (i=xs; i<xs+xm; i++) {
      x[j][i].u     = 0.0;
      x[j][i].v     = 0.0;
      x[j][i].omega = 0.0;
    }
  }
  ierr = DAVecRestoreArray(da,X,&x);CHKERRQ(ierr);
  return 0;
}
Пример #14
0
/*@
   DAAppSetADElementFunctionGradient - Set routine that evaluates the
   local part of a function on a 2-dimensional DA with 1 degree of freedom. 

   Collective on TAO_APPLICATION

   Input Parameters:
+  daapp - the TAO_DA_APPLICATION solver context
.  funcgrad - local function gradient routine
.  flops - the number of flops done performed in the funcgrad routine
-  fgctx - [optional] user-defined context for private data for the evaluation.

   Calling sequence of funcgrad:
$     int funcgrad(int coordinates[2], PetscScalar x[4], double *f, PetscScalar g[4], void* ctx)

+    coord - the global coordinates [i j] in each direction of the DA
.    x - the variables on the DA ( da[j][i], da[j][j+1], da[j+1][i], da[j+1][i+1] ) (bottom left, bottom right, top left, top right)
.    g - the ADIC differentiated objective function with respect to each variable
-    ctx - user defined context
   
   Note: This function requires ADIC to be installed and the ADIC-specific variables to be set in
         $TAO_DIR/bmake/packages.$PETSC_ARCH

   Level: intermediate

.keywords: DA, gradient, ADIC

.seealso:  DAAppSetObjectiveAndGradientRoutine(), DAAppSetElementObjectiveAndGradientRoutine()
@*/
int DAAppSetADElementFunctionGradient(TAO_APPLICATION daapplication, 
					 int (*funcgrad)(int[2],DERIV_TYPE[4],DERIV_TYPE*,void*), 
					 int flops, void *ctx){
  int i,n,info;
  int dim,dof,s;
  DAStencilType st;
  TaoDA2D1DOFADICFGCtx *fgctx;
  DA da;

  PetscFunctionBegin;
  info=DAAppGetNumberOfDAGrids(daapplication,&n); CHKERRQ(info);
  for (i=0;i<n;i++){
    info = DAAppGetDA(daapplication, i, &da); CHKERRQ(info);
    info = DAGetInfo(da,&dim,0,0,0,0,0,0,&dof,&s,0,&st); CHKERRQ(info);
    if (dim!=2){
      SETERRQ(1,"TAO DA ERROR: DA must have dimension of 2");}
    if (dof!=1){
      SETERRQ(1,"TAO DA ERROR: DA must have exactly 1 degree of freedom per node");}
    if (s!=1){
      SETERRQ(1,"TAO DA ERROR: DA stencil width must equal 1"); }
    if (st!=DA_STENCIL_BOX){
      SETERRQ(1,"TAO DA ERROR: DA stencil must be DA_STENCIL_BOX");}
  }
  PetscNew(TaoDA2D1DOFADICFGCtx,&fgctx);
  //  ad_AD_Init(4);
  ad_AD_Init(ad_GRAD_MAX);
  ad_AD_SetIndepArray(fgctx->adX,4);
  ad_AD_SetIndepDone();
  fgctx->computeadicfunctiongradient=funcgrad;
  fgctx->elementfgctx=ctx;
  fgctx->elementfgflops=flops;
  info = DAAppSetObjectiveAndGradientRoutine(daapplication, TaoDA2dLoopADFunctionGradient, (void*)fgctx); 
  CHKERRQ(info);
  info = TaoAppSetDestroyRoutine(daapplication,TaoApplicationFreeMemory, (void*)fgctx); CHKERRQ(info);
  info = TaoAppSetDestroyRoutine(daapplication, TaoShutDownADICQQQQ, 0); CHKERRQ(info);
  info = PetscInfo(daapplication,"Set objective function pointer for TAO_DA_APPLICATION object.\n"); CHKERRQ(info);
  PetscFunctionReturn(0);
}
Пример #15
0
static int MyGridMonitorBefore(TAO_APPLICATION myapp, DA da, PetscInt level, void *ctx) {

  AppCtx *user = (AppCtx*)ctx;
  int info;
  PetscInt mx,my;

  info = DAGetInfo(da,PETSC_NULL,&mx,&my,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,
		   PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(info);
  user->mx = mx;
  user->my = my;
  user->hx = (user->r - user->l) / (user->mx - 1);
  user->hy = (user->t - user->b) / (user->my - 1);
  user->area = 0.5 * user->hx * user->hy;
  user->fgctx.hx   = user->hx;
  user->fgctx.hy   = user->hy;
  user->fgctx.area = user->area;

  user->bmx=(PetscInt)((mx+1)*user->fx); user->bmy=(PetscInt)((my+1)*user->fy); 

  PetscPrintf(MPI_COMM_WORLD,"Grid: %d,    mx: %d     my: %d   \n",level,mx,my);

  return 0;
}
Пример #16
0
/* Form initial guess for Physic 2 */
PetscErrorCode FormInitialGuessLocal2(DMMG dmmg,Vec X)
{
  AppCtx         *user = (AppCtx*)dmmg->user;
  DA             da = (DA)dmmg->dm;
  PetscInt       i,j,mx,xs,ys,xm,ym;
  PetscErrorCode ierr;
  PetscReal      grashof,dx;
  Field2         **x;

  grashof = user->grashof;
  ierr = DAGetInfo(da,0,&mx,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  dx  = 1.0/(mx-1);

  ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr);

  ierr = DAVecGetArray(da,X,&x);CHKERRQ(ierr);
  for (j=ys; j<ys+ym; j++) {
    for (i=xs; i<xs+xm; i++) {
      x[j][i].temp  = (grashof>0)*i*dx;  
    }
  }
  ierr = DAVecRestoreArray(da,X,&x);CHKERRQ(ierr);
  return 0;
}
Пример #17
0
extern PetscErrorCode DefiantComputeTransmissibilities(
    BlackOilReservoirSimulation* MySim) {
  PetscErrorCode ierr;
  PetscInt i, j, k, mx, my, mz, xm, ym, zm, xs, ys, zs;
  PetscScalar ***LocalFlowMask;
  /* Area * Permeability divided by height */
  PetscScalar ***LocalAKHx1m, ***LocalAKHx2m, ***LocalAKHx3m;
  PetscScalar ***LocalAKHx1p, ***LocalAKHx2p, ***LocalAKHx3p;
  /* Local viscosity at the faces */
  PetscScalar ***LocalMuox1m, ***LocalMuox1p, ***LocalMuwx1m, ***LocalMuwx1p,
      ***LocalMugx1m, ***LocalMugx1p;
  PetscScalar ***LocalMuox2m, ***LocalMuox2p, ***LocalMuwx2m, ***LocalMuwx2p,
      ***LocalMugx2m, ***LocalMugx2p;
  PetscScalar ***LocalMuox3m, ***LocalMuox3p, ***LocalMuwx3m, ***LocalMuwx3p,
      ***LocalMugx3m, ***LocalMugx3p;
  /* Relative Permeabilities at the faces */
  PetscScalar ***LocalRelPermox1m, ***LocalRelPermox1p, ***LocalRelPermox2m,
      ***LocalRelPermox2p, ***LocalRelPermox3m, ***LocalRelPermox3p;
  PetscScalar ***LocalRelPermwx1m, ***LocalRelPermwx1p, ***LocalRelPermwx2m,
      ***LocalRelPermwx2p, ***LocalRelPermwx3m, ***LocalRelPermwx3p;
  PetscScalar ***LocalRelPermgx1m, ***LocalRelPermgx1p, ***LocalRelPermgx2m,
      ***LocalRelPermgx2p, ***LocalRelPermgx3m, ***LocalRelPermgx3p;
  /* Volume factors at cell center */
  PetscScalar ***LocalBo, ***LocalBw, ***LocalBg;
  /* Volume factors at cell faces */
  PetscScalar ***LocalBox1p, ***LocalBox2p, ***LocalBox3p;
  PetscScalar ***LocalBox1m, ***LocalBox2m, ***LocalBox3m;
  PetscScalar ***LocalBwx1p, ***LocalBwx2p, ***LocalBwx3p;
  PetscScalar ***LocalBwx1m, ***LocalBwx2m, ***LocalBwx3m;
  PetscScalar ***LocalBgx1p, ***LocalBgx2p, ***LocalBgx3p;
  PetscScalar ***LocalBgx1m, ***LocalBgx2m, ***LocalBgx3m;
  /* Transmissibility For Oil*/
  PetscScalar ***LocalTox1p, ***LocalTox2p, ***LocalTox3p;
  PetscScalar ***LocalTox1m, ***LocalTox2m, ***LocalTox3m;
  /* Transmissibility For Water*/
  PetscScalar ***LocalTwx1p, ***LocalTwx2p, ***LocalTwx3p;
  PetscScalar ***LocalTwx1m, ***LocalTwx2m, ***LocalTwx3m;
  /* Transmissibility For Gas*/
  PetscScalar ***LocalTgx1p, ***LocalTgx2p, ***LocalTgx3p;
  PetscScalar ***LocalTgx1m, ***LocalTgx2m, ***LocalTgx3m;

  PetscFunctionBegin;
  /* Get dimensions and extents of the local vectors */
  ierr = DAGetInfo(MySim->SimDA, 0, &mx, &my, &mz, 0, 0, 0, 0, 0, 0, 0);CHKERRQ(ierr);
  ierr = DAGetCorners(MySim->SimDA, &xs, &ys, &zs, &xm, &ym, &zm);CHKERRQ(ierr);
  /* Grab the data for the flow field */
  ierr = DAVecGetArray(MySim->SimDA, MySim->FlowMask, &LocalFlowMask);CHKERRQ(ierr);
  /* Grab the local data for area * permeability divided by height */
  ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx1m, &LocalAKHx1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx2m, &LocalAKHx2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx3m, &LocalAKHx3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx1p, &LocalAKHx1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx2p, &LocalAKHx2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx3p, &LocalAKHx3p);CHKERRQ(ierr);
  /* Grab the local data for the face viscosities */
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muox1m, &LocalMuox1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muox1p, &LocalMuox1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx1m, &LocalMuwx1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx1p, &LocalMuwx1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx1m, &LocalMugx1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx1p, &LocalMugx1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muox2m, &LocalMuox2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muox2p, &LocalMuox2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx2m, &LocalMuwx2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx2p, &LocalMuwx2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx2m, &LocalMugx2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx2p, &LocalMugx2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muox3m, &LocalMuox3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muox3p, &LocalMuox3p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx3m, &LocalMuwx3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx3p, &LocalMuwx3p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx3m, &LocalMugx3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx3p, &LocalMugx3p);CHKERRQ(ierr);
  /* Grab the local data for the face Relative Permeabilities */
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox1m, &LocalRelPermox1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox1p, &LocalRelPermox1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox2m, &LocalRelPermox2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox2p, &LocalRelPermox2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox3m, &LocalRelPermox3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox3p, &LocalRelPermox3p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx1m, &LocalRelPermwx1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx1p, &LocalRelPermwx1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx2m, &LocalRelPermwx2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx2p, &LocalRelPermwx2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx3m, &LocalRelPermwx3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx3p, &LocalRelPermwx3p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx1m, &LocalRelPermgx1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx1p, &LocalRelPermgx1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx2m, &LocalRelPermgx2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx2p, &LocalRelPermgx2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx3m, &LocalRelPermgx3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx3p, &LocalRelPermgx3p);CHKERRQ(ierr);
  /* Grab the local data for volume factors at the cell centers */
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bo, &LocalBo);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bw, &LocalBw);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bg, &LocalBg);CHKERRQ(ierr);
  /* Grab the local data for Volume factors at the faces */
  ierr = DAVecGetArray(MySim->SimDA, MySim->Box1p, &LocalBox1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Box2p, &LocalBox2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Box3p, &LocalBox3p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Box1m, &LocalBox1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Box2m, &LocalBox2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Box3m, &LocalBox3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx1p, &LocalBwx1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx2p, &LocalBwx2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx3p, &LocalBwx3p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx1m, &LocalBwx1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx2m, &LocalBwx2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx3m, &LocalBwx3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx1p, &LocalBgx1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx2p, &LocalBgx2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx3p, &LocalBgx3p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx1m, &LocalBgx1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx2m, &LocalBgx2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx3m, &LocalBgx3m);CHKERRQ(ierr);
  /* Grab the local data for the transmissibilities */
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tox1m, &LocalTox1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tox1p, &LocalTox1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Twx1m, &LocalTwx1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Twx1p, &LocalTwx1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx1m, &LocalTgx1m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx1p, &LocalTgx1p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tox2m, &LocalTox2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tox2p, &LocalTox2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Twx2m, &LocalTwx2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Twx2p, &LocalTwx2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx2m, &LocalTgx2m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx2p, &LocalTgx2p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tox3m, &LocalTox3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tox3p, &LocalTox3p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Twx3m, &LocalTwx3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Twx3p, &LocalTwx3p);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx3m, &LocalTgx3m);CHKERRQ(ierr);
  ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx3p, &LocalTgx3p);CHKERRQ(ierr);

  for (k = zs; k < zs + zm; k++) {
    for (j = ys; j < ys + ym; j++) {
      for (i = xs; i < xs + xm; i++) {
        if (i == 0 || j == 0 || k == 0 || i == mx - 1 || j == my - 1 || k == mz
            - 1) {
        } else if (ABS(LocalFlowMask[k][j][i]-FLUID_FLOW) < EPSILON) {
          /* Transmissibility */
          LocalTox1m[k][j][i] = LocalRelPermox1m[k][j][i]
              * LocalAKHx1m[k][j][i] / LocalMuox1m[k][j][i] / LocalBox1m[k][j][i];
          LocalTox1p[k][j][i] = LocalRelPermox1p[k][j][i]
              * LocalAKHx1p[k][j][i] / LocalMuox1p[k][j][i] / LocalBox1p[k][j][i];
          LocalTox2m[k][j][i] = LocalRelPermox2m[k][j][i]
              * LocalAKHx2m[k][j][i] / LocalMuox2m[k][j][i] / LocalBox2m[k][j][i];
          LocalTox2p[k][j][i] = LocalRelPermox2p[k][j][i]
              * LocalAKHx2p[k][j][i] / LocalMuox2p[k][j][i] / LocalBox2p[k][j][i];
          LocalTox3m[k][j][i] = LocalRelPermox3m[k][j][i]
              * LocalAKHx3m[k][j][i] / LocalMuox3m[k][j][i] / LocalBox3m[k][j][i];
          LocalTox3p[k][j][i] = LocalRelPermox3p[k][j][i]
              * LocalAKHx3p[k][j][i] / LocalMuox3p[k][j][i] / LocalBox3p[k][j][i];

          LocalTwx1m[k][j][i] = LocalRelPermwx1m[k][j][i]
              * LocalAKHx1m[k][j][i] / LocalMuwx1m[k][j][i] / LocalBwx1m[k][j][i];
          LocalTwx1p[k][j][i] = LocalRelPermwx1p[k][j][i]
              * LocalAKHx1p[k][j][i] / LocalMuwx1p[k][j][i] / LocalBwx1p[k][j][i];
          LocalTwx2m[k][j][i] = LocalRelPermwx2m[k][j][i]
              * LocalAKHx2m[k][j][i] / LocalMuwx2m[k][j][i] / LocalBwx2m[k][j][i];
          LocalTwx2p[k][j][i] = LocalRelPermwx2p[k][j][i]
              * LocalAKHx2p[k][j][i] / LocalMuwx2p[k][j][i] / LocalBwx2p[k][j][i];
          LocalTwx3m[k][j][i] = LocalRelPermwx3m[k][j][i]
              * LocalAKHx3m[k][j][i] / LocalMuwx3m[k][j][i] / LocalBwx3m[k][j][i];
          LocalTwx3p[k][j][i] = LocalRelPermwx3p[k][j][i]
              * LocalAKHx3p[k][j][i] / LocalMuwx3p[k][j][i] / LocalBwx3p[k][j][i];

          LocalTgx1m[k][j][i] = LocalRelPermgx1m[k][j][i]
              * LocalAKHx1m[k][j][i] / LocalMugx1m[k][j][i] / LocalBgx1m[k][j][i];
          LocalTgx1p[k][j][i] = LocalRelPermgx1p[k][j][i]
              * LocalAKHx1p[k][j][i] / LocalMugx1p[k][j][i] / LocalBgx1p[k][j][i];
          LocalTgx2m[k][j][i] = LocalRelPermgx2m[k][j][i]
              * LocalAKHx2m[k][j][i] / LocalMugx2m[k][j][i] / LocalBgx2m[k][j][i];
          LocalTgx2p[k][j][i] = LocalRelPermgx2p[k][j][i]
              * LocalAKHx2p[k][j][i] / LocalMugx2p[k][j][i] / LocalBgx2p[k][j][i];
          LocalTgx3m[k][j][i] = LocalRelPermgx3m[k][j][i]
              * LocalAKHx3m[k][j][i] / LocalMugx3m[k][j][i] / LocalBgx3m[k][j][i];
          LocalTgx3p[k][j][i] = LocalRelPermgx3p[k][j][i]
              * LocalAKHx3p[k][j][i] / LocalMugx3p[k][j][i] / LocalBgx3p[k][j][i];
        }
      }
    }
  }

  /* Restore the new arrays to their reightful place */
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox1m, &LocalTox1m);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox1p, &LocalTox1p);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx1m, &LocalTwx1m);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx1p, &LocalTwx1p);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx1m, &LocalTgx1m);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx1p, &LocalTgx1p);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox2m, &LocalTox2m);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox2p, &LocalTox2p);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx2m, &LocalTwx2m);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx2p, &LocalTwx2p);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx2m, &LocalTgx2m);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx2p, &LocalTgx2p);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox3m, &LocalTox3m);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox3p, &LocalTox3p);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx3m, &LocalTwx3m);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx3p, &LocalTwx3p);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx3m, &LocalTgx3m);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx3p, &LocalTgx3p);CHKERRQ(ierr);

  /* Begin Assembly for vectors */
  ierr = VecAssemblyBegin(MySim->Tox1p);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tox2p);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tox3p);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tox1m);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tox2m);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tox3m);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Twx1p);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Twx2p);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Twx3p);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Twx1m);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Twx2m);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Twx3m);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tgx1p);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tgx2p);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tgx3p);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tgx1m);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tgx2m);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(MySim->Tgx3m);CHKERRQ(ierr);

  /* And end Assembly */
  ierr = VecAssemblyEnd(MySim->Tox1p);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tox2p);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tox3p);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tox1m);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tox2m);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tox3m);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Twx1p);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Twx2p);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Twx3p);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Twx1m);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Twx2m);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Twx3m);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tgx1p);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tgx2p);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tgx3p);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tgx1m);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tgx2m);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(MySim->Tgx3m);CHKERRQ(ierr);

  PetscFunctionReturn(0);
}
Пример #18
0
void getForces(Vec params, std::vector<Vec> &forces, DA da, timeInfo ti, int numParams) {
#ifdef __DEBUG__
  std::cout << RED"Entering "NRM << __func__ << std::endl;
#endif
  // Generate the force vector based on the current parameters ...
  // F = Sum { B_i a_i}
  
  PetscScalar * pVec;
  VecGetArray(params, &pVec);
  // Clear the Forces
  for (unsigned int i=0; i<forces.size(); i++) {
    if (forces[i] != NULL) {
      VecDestroy(forces[i]);
    }
  }
  forces.clear();

  unsigned int numSteps = (unsigned int)(ceil(( ti.stop - ti.start)/ti.step));
  // create and initialize to 0
  for (unsigned int i=0; i<numSteps+1; i++) {
    Vec tmp;
    DACreateGlobalVector(da, &tmp);
    VecZeroEntries(tmp);
    forces.push_back(tmp);
  }

  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  PetscScalar ***tauArray;

  unsigned int paramTimeSteps = (unsigned int)(ceil(( (double)(numSteps))/ ((double)(2*numParams)) ));
  double acx,acy,acz;

  int x, y, z, m, n, p;
  int mx,my,mz;

  DAGetCorners(da, &x, &y, &z, &m, &n, &p);
  DAGetInfo(da,0, &mx, &my, &mz, 0,0,0,0,0,0,0);

  double hx = 1.0/(mx-1.0);

  for (int b=0; b<numParams; b++) {
    std::vector<Vec> tau;
    unsigned int tBegin = paramTimeSteps*b;
    unsigned int tEnd   = tBegin + numSteps/2; // paramTimeSteps*(b+2);

    // std::cout << "For param " << b << ": Time step range is " << tBegin << " -> " << tEnd << std::endl; 
    for (unsigned int t=0; t<numSteps+1; t++) {
      double newTime = (ti.step*(t-tBegin)*numSteps)/((double)(paramTimeSteps));
      
      if ( (t>=tBegin) && (t<=tEnd)) {
        DAVecGetArray(da, forces[t], &tauArray);
        for (int k = z; k < z + p ; k++) {
          for (int j = y; j < y + n; j++) {
            for (int i = x; i < x + m; i++) {
              acx = (i)*hx; acy = (j)*hx; acz = (k)*hx;
              tauArray[k][j][i] += pVec[b]*sin(M_PI*newTime)*cos(2*M_PI*acx)*cos(2*M_PI*acy)*cos(2*M_PI*acz);
            }
          }
        }
        DAVecRestoreArray ( da, forces[t], &tauArray ) ;
      }
    }
  }
  VecRestoreArray(params, &pVec);

#ifdef __DEBUG__
  // Get the norms of the forces ... just to be safe ..
  double fNorm1, fNorm2;

  for (unsigned int i=0; i<forces.size(); i++) {
    VecNorm(forces[i], NORM_INFINITY, &fNorm1);
    VecNorm(forces[i], NORM_2, &fNorm2);
    PetscPrintf(0, "Force Norms at timestep %d are %g and %g\n", i, fNorm1, fNorm2);
  }
#endif
  
#ifdef __DEBUG__
  std::cout << GRN"Leaving "NRM << __func__ << std::endl;
#endif
}
Пример #19
0
int main(int argc, char **argv)
{    
  PetscInitialize(&argc, &argv, "wave.opt", help);

  int rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  double startTime, endTime;
  
  int Ns = 32;
  unsigned int dof = 1;

  // double dtratio = 1.0;
  DA  da;         // Underlying DA

  Vec rho;        // density - elemental scalar
  Vec nu;         // Lame parameter - lambda - elemental scalar

  std::vector < std::vector<Vec> > fBasis;        // the scalar activation - nodal scalar
  // std::vector<Vec> truth;        // the ground truth.

  // Initial conditions
  Vec initialDisplacement; 
  Vec initialVelocity;

  timeInfo ti;

  // get Ns
  CHKERRQ ( PetscOptionsGetInt(0,"-Ns", &Ns,0) );

  double t0 = 0.0;
  double dt = 1.0/(Ns);
  double t1 = 1.0;

  double nuVal = 1.0;
  double beta = 0.0001;
  int numParams = 5;

  CHKERRQ ( PetscOptionsGetInt(0,"-nump",&numParams,0) );

  CHKERRQ ( PetscOptionsGetScalar(0,"-t0",&t0,0) );
  CHKERRQ ( PetscOptionsGetScalar(0,"-t1",&t1,0) );
  CHKERRQ ( PetscOptionsGetScalar(0,"-dt",&dt,0) );
  CHKERRQ ( PetscOptionsGetScalar(0,"-nu",&nuVal,0) );
  CHKERRQ ( PetscOptionsGetScalar(0,"-beta",&beta,0) );
  // CHKERRQ ( PetscOptionsGetString(PETSC_NULL, "-pn", problemName, PETSC_MAX_PATH_LEN-1, PETSC_NULL));

  // Time info for timestepping
  ti.start = t0;
  ti.stop  = t1;
  ti.step  = dt;

  if (!rank) {
    std::cout << "Problem size is " << Ns+1 << " spatially and NT = " << (int)ceil(1.0/dt) << std::endl << std::endl;
    std::cout << "Number of parameters is " << numParams << std::endl;
  }
  // create DA
  CHKERRQ ( DACreate3d ( PETSC_COMM_WORLD, DA_NONPERIODIC, DA_STENCIL_BOX, 
                         Ns+1, Ns+1, Ns+1, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE,
                         1, 1, 0, 0, 0, &da) );

  massMatrix *Mass = new massMatrix(feMat::PETSC); // Mass Matrix
  stiffnessMatrix *Stiffness = new stiffnessMatrix(feMat::PETSC); // Stiffness matrix
  waveDamping *Damping = new waveDamping(feMat::PETSC); // Damping Matrix

  fdynamicVector *Force = new fdynamicVector(feVec::PETSC); // Force Vector

  // create vectors 
  CHKERRQ( DACreateGlobalVector(da, &rho) );
  CHKERRQ( DACreateGlobalVector(da, &nu) );

  CHKERRQ( DACreateGlobalVector(da, &initialDisplacement) );
  CHKERRQ( DACreateGlobalVector(da, &initialVelocity) );

  // Set initial conditions
  CHKERRQ( VecSet ( initialDisplacement, 0.0) ); 
  CHKERRQ( VecSet ( initialVelocity, 0.0) );

  VecZeroEntries( nu );
  VecZeroEntries( rho );

  CHKERRQ( VecSet ( nu, nuVal) ); 
  CHKERRQ( VecSet ( rho, 1.0) );

  int x, y, z, m, n, p;
  int mx,my,mz;

  CHKERRQ( DAGetCorners(da, &x, &y, &z, &m, &n, &p) ); 
  CHKERRQ( DAGetInfo(da,0, &mx, &my, &mz, 0,0,0,0,0,0,0) ); 

  double acx,acy,acz;
  double hx = 1.0/((double)Ns);

  // allocate for temporary buffers ...
  // unsigned int elemSize = Ns*Ns*Ns;
  // std::cout << "Elem size is " << elemSize << std::endl;
  // unsigned int nodeSize = (Ns+1)*(Ns+1)*(Ns+1);

  // Now set the activation ...
  unsigned int numSteps = (unsigned int)(ceil(( ti.stop - ti.start)/ti.step));

 // Vec tauVec;

  // PetscScalar ***tauArray;

  unsigned int paramTimeSteps = (unsigned int)(ceil(( (double)(numSteps))/ ((double)(2*numParams)) ));

  /*
  for (int b=0; b<numParams; b++) {
    std::vector<Vec> tau;
    unsigned int tBegin = paramTimeSteps*b;
    unsigned int tEnd   = tBegin + numSteps/2; // paramTimeSteps*(b+2);

    // std::cout << "For param " << b << ": Time step range is " << tBegin << " -> " << tEnd << std::endl; 
    for (unsigned int t=0; t<numSteps+1; t++) {
      double newTime = (dt*(t-tBegin)*numSteps)/((double)(paramTimeSteps));
     // double fff = 0.0;
      CHKERRQ( DACreateGlobalVector(da, &tauVec) );
      CHKERRQ( VecSet( tauVec, 0.0));

      if ( (t>=tBegin) && (t<=tEnd)) {
        CHKERRQ(DAVecGetArray(da, tauVec, &tauArray));
        for (int k = z; k < z + p ; k++) {
          for (int j = y; j < y + n; j++) {
            for (int i = x; i < x + m; i++) {
              acx = (i)*hx; acy = (j)*hx; acz = (k)*hx;
              tauArray[k][j][i] = sin(M_PI*newTime)*cos(2*M_PI*acx)*cos(2*M_PI*acy)*cos(2*M_PI*acz);
            }
          }
        }
        CHKERRQ( DAVecRestoreArray ( da, tauVec, &tauArray ) );
      }
      tau.push_back(tauVec);
    }
    fBasis.push_back(tau);
  }
  */
 // std::cout << "Finished setting basis" << std::endl;

  /*
  // Set initial velocity ...
  CHKERRQ(DAVecGetArray(da, initialVelocity, &solArray));

  for (int k = z; k < z + p ; k++) {
  for (int j = y; j < y + n; j++) {
  for (int i = x; i < x + m; i++) {
  acx = (i)*hx; acy = (j)*hx; acz = (k)*hx;
  solArray[k][j][i] = M_PI*cos(2*M_PI*acx)*cos(2*M_PI*acy)*cos(2*M_PI*acz);
  }
  }
  }
  CHKERRQ( DAVecRestoreArray ( da, initialVelocity, &solArray ) );
  */

  std::vector<Vec> newF;

  Vec alpha;
  PetscScalar *avec;

  VecCreateSeq(PETSC_COMM_SELF, numParams, &alpha);
  /*
  VecCreate(PETSC_COMM_WORLD, &alpha);
  VecSetSizes(alpha, numParams, PETSC_DECIDE);
  VecSetFromOptions(alpha);
  */

  VecGetArray(alpha, &avec);

  for (int j=0; j<numParams; j++)
    avec[j] = 0.5 + 0.5*j;

  VecRestoreArray(alpha, &avec);

  // getForces(alpha, fBasis, newF);
  getForces(alpha, newF, da, ti, numParams);

  // Setup Matrices and Force Vector ...
  Mass->setProblemDimensions(1.0, 1.0, 1.0);
  Mass->setDA(da);
  Mass->setDof(dof);
  Mass->setNuVec(rho);

  Stiffness->setProblemDimensions(1.0, 1.0, 1.0);
  Stiffness->setDA(da);
  Stiffness->setDof(dof);
  Stiffness->setNuVec(nu);

  Damping->setAlpha(0.0);
  Damping->setBeta(0.00075);
  Damping->setMassMatrix(Mass);
  Damping->setStiffnessMatrix(Stiffness);
  Damping->setDA(da);
  Damping->setDof(dof);

  // Force Vector
  Force->setProblemDimensions(1.0,1.0,1.0);
  Force->setDA(da);
  Force->setFDynamic(newF);
  Force->setTimeInfo(&ti);

  // Newmark time stepper ...
  newmark *ts = new newmark; 

  ts->setMassMatrix(Mass);
  ts->setDampingMatrix(Damping);
  ts->setStiffnessMatrix(Stiffness);
  ts->damp(false);
  ts->setTimeFrames(1);
  ts->storeVec(true);
  ts->setAdjoint(false);

  ts->setForceVector(Force);

  ts->setInitialDisplacement(initialDisplacement);
  ts->setInitialVelocity(initialVelocity);

  ts->setTimeInfo(&ti);
  ts->setAdjoint(false); // set if adjoint or forward

  ts->init(); // initialize IMPORTANT 
 // if (!rank)
 //   std::cout << RED"Starting initial forward solve"NRM << std::endl;
  ts->solve();// solve 
 // if (!rank)
 // std::cout << GRN"Finished with initial forward solve"NRM << std::endl;

  std::vector<Vec> solvec = ts->getSolution();
  // Now lets check the error ...
  // Vec nr;
  // concatenateVecs(solvec, nr);

  // VecDestroy(nr);
  // VecDestroy(gt);

  // std::cout << std::endl;
  /*************
   *  INVERSE  *
  *************/

  // True solution is tau ... we want to recover it.
  // The observations in this case are, solvec

  /* Set very initial guess for the inverse problem*/

   // Now can clear memory ...

  /*
  for (int i=0; i<newF.size(); i++) {
    if (newF[i] != NULL) {
      VecDestroy(newF[i]);
    }
  }
  newF.clear();

  for (int i=0; i<solvec.size(); i++) {
    if (solvec[i] != NULL) {
      VecDestroy(solvec[i]);
    }
  } 
  solvec.clear();

  ts->destroy();

  VecDestroy(rho);
  VecDestroy(nu);
  VecDestroy(initialDisplacement);
  VecDestroy(initialVelocity);

  VecDestroy(alpha);

  DADestroy(da);

  PetscFinalize();

  return 0;
  */

  Vec gt, nr;
  concatenateVecs(solvec, gt);

  Vec guess;
  VecDuplicate(alpha, &guess);
  VecZeroEntries(guess);
  // VecDuplicate(guess, &Out);
  // VecZeroEntries(Out);

  // double norm;
  /*
     PetscRandom rctx;
     PetscRandomCreate(PETSC_COMM_WORLD, &rctx);
     PetscRandomSetFromOptions(rctx);
     VecSetRandom(guess, rctx);
     VecNorm(guess, NORM_2, &norm);
     PetscPrintf(0, "guess norm = %g\n", norm);
     */


  // double errnorm;
  // double exsolnorm;

  // Inverse solver set up
  // std::cout << RED"Setting up Inverse Solver"NRM << std::endl;
  parametricWaveInverse* hyperInv = new parametricWaveInverse;
  // std::cout << GRN"Finished setting up Inverse Solver"NRM << std::endl;


  hyperInv->setTimeStepper(ts);    // set the timestepper
  hyperInv->setForwardInitialConditions(initialDisplacement, initialVelocity);
  // std::cout << RED"Setting initial guess"NRM << std::endl;
  // hyperInv->setInitialGuess(truth);// set the initial guess 
  hyperInv->setInitialGuess(guess);// set the initial guess 
  // std::cout << GRN"Done setting initial guess"NRM << std::endl;
  hyperInv->setRegularizationParameter(beta); // set the regularization paramter
  hyperInv->setAdjoints(solvec); // set the data for the problem 

  // hyperInv->setForceBasis(fBasis);
  hyperInv->setNumberOfParameter(numParams);

  // std::cout << RED"Initializing Inverse Solver"NRM << std::endl;
  hyperInv->init(); // initialize the inverse solver

 // if (!rank)
 //   std::cout << RED"Starting Inverse Solve"NRM << std::endl;
  startTime = MPI_Wtime();
  hyperInv->solve(); // solve
  endTime = MPI_Wtime();
 // if (!rank)
 //   std::cout << GRN"FINISHED HESSIAN SOLVE"NRM << std::endl;

  hyperInv->getCurrentControl(guess); // get the solution 

  hyperInv->destroy();

  /*
 for (int i=0; i<solvec.size(); i++) {
    if (solvec[i] != NULL) {
      VecDestroy(solvec[i]);
    }
  } 
  solvec.clear();
  */
  // VecView(guess, 0);

  if (!rank)
    std::cout << std::endl << "Error Norms " << std::endl;

  Vec Err;
  double gtNorm, solNorm, errNorm;
  VecDuplicate(guess, &Err);
  VecWAXPY(Err, -1.0, guess, alpha);
  VecNorm(alpha, NORM_2, &gtNorm);
  VecNorm(guess, NORM_2, &solNorm);
  VecNorm(Err, NORM_2, &errNorm);

  if (!rank) {
    std::cout << "The norms are " << gtNorm << ", " << solNorm << ", " << errNorm << std::endl;
    std::cout << "Relative error is " << errNorm/gtNorm << std::endl;
  }
  // Now we shall do another forward solve ...
  getForces(guess, newF, da, ti, numParams);
  Force->setFDynamic(newF);

  ts->setInitialDisplacement(initialDisplacement);
  ts->setInitialVelocity(initialVelocity);
  ts->setAdjoint(false);
  ts->clearMonitor();
  ts->solve();

  std::vector<Vec> solvec2 = ts->getSolution();

  ts->destroy();

  concatenateVecs(solvec2, nr);

   // Now can clear memory ...
  for (int i=0; i<solvec2.size(); i++) {
    if (solvec2[i] != NULL) {
      VecDestroy(solvec2[i]);
    }
  }
  solvec2.clear();

   // Now can clear memory ...
  for (int i=0; i<newF.size(); i++) {
    if (newF[i] != NULL) {
      VecDestroy(newF[i]);
    }
  }
  newF.clear();
/*
  for (unsigned int i=0; i<truth.size(); i++) {
    VecNorm(truth[i], NORM_2, &gtNorm);
    VecNorm(solvec[i], NORM_2, &solNorm);
    VecAXPY(solvec[i], -1.0, truth[i]);
    VecNorm(solvec[i], NORM_2, &errNorm);
    PetscPrintf(0, "Ground truth at timestep %d is %g, %g, %g\n", i, gtNorm, solNorm, errNorm);
    // PetscPrintf(0, "Relative Error at timestep %d is %g\n", i, errNorm/gtNorm);
  }
  */
  VecNorm(gt, NORM_2, &gtNorm);
  VecAXPY(nr, -1.0, gt);
  VecNorm(nr, NORM_2, &errNorm);

  if (!rank)
    std::cout <<  "Total Relative error on state is " << errNorm/gtNorm << std::endl;
  
  if (!rank)
    std::cout << "Wall time is " << endTime - startTime << std::endl;


  VecDestroy(gt);
  VecDestroy(nr);
  VecDestroy(Err);
  VecDestroy(alpha);
  VecDestroy(guess);

  VecDestroy(rho);
  VecDestroy(nu);
  VecDestroy(initialDisplacement);
  VecDestroy(initialVelocity);

  DADestroy(da);

  PetscFinalize();
}
Пример #20
0
PetscErrorCode ComputeMatrix(DA da,Mat B)
{
  PetscErrorCode ierr;
  PetscInt       i,j,k,mx,my,mz,xm,ym,zm,xs,ys,zs,dof,k1,k2,k3;
  PetscScalar    *v,*v_neighbor,Hx,Hy,Hz,HxHydHz,HyHzdHx,HxHzdHy;
  MatStencil     row,col;
 
  PetscFunctionBegin;
  ierr = DAGetInfo(da,0,&mx,&my,&mz,0,0,0,&dof,0,0,0);CHKERRQ(ierr); 
  /* For simplicity, this example only works on mx=my=mz */
  if ( mx != my || mx != mz) SETERRQ3(1,"This example only works with mx %d = my %d = mz %d\n",mx,my,mz);

  Hx = 1.0 / (PetscReal)(mx-1); Hy = 1.0 / (PetscReal)(my-1); Hz = 1.0 / (PetscReal)(mz-1);
  HxHydHz = Hx*Hy/Hz; HxHzdHy = Hx*Hz/Hy; HyHzdHx = Hy*Hz/Hx;

  ierr = PetscMalloc((2*dof*dof+1)*sizeof(PetscScalar),&v);CHKERRQ(ierr);
  v_neighbor = v + dof*dof;
  ierr = PetscMemzero(v,(2*dof*dof+1)*sizeof(PetscScalar));CHKERRQ(ierr);
  k3 = 0;
  for (k1=0; k1<dof; k1++){
    for (k2=0; k2<dof; k2++){
      if (k1 == k2){
        v[k3]          = 2.0*(HxHydHz + HxHzdHy + HyHzdHx);
        v_neighbor[k3] = -HxHydHz;
      } else {
	v[k3] = k1/(dof*dof); ;
	v_neighbor[k3] = k2/(dof*dof);
      }	
      k3++;
    }
  }
  ierr = DAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
  
  for (k=zs; k<zs+zm; k++){
    for (j=ys; j<ys+ym; j++){
      for(i=xs; i<xs+xm; i++){
        row.i = i; row.j = j; row.k = k;
	if (i==0 || j==0 || k==0 || i==mx-1 || j==my-1 || k==mz-1){ /* boudary points */	 
	  ierr = MatSetValuesBlockedStencil(B,1,&row,1,&row,v,INSERT_VALUES);CHKERRQ(ierr);
        } else { /* interior points */
          /* center */
          col.i = i; col.j = j; col.k = k;
          ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v,INSERT_VALUES);CHKERRQ(ierr);          
          
          /* x neighbors */
	  col.i = i-1; col.j = j; col.k = k;
          ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr);
	  col.i = i+1; col.j = j; col.k = k;
	  ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr);
	 
	  /* y neighbors */
	  col.i = i; col.j = j-1; col.k = k;
	  ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr);
	  col.i = i; col.j = j+1; col.k = k;
	  ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr);
	 
          /* z neighbors */
	  col.i = i; col.j = j; col.k = k-1;
	  ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr);
	  col.i = i; col.j = j; col.k = k+1;
          ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr);
        }
      }
    }
  }
  ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = PetscFree(v);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Пример #21
0
/* 
   FormFunction - Evaluates nonlinear function, F(x).

   Input Parameters:
.  snes - the SNES context
.  x - input vector
.  ctx - optional user-defined context, as set by SNESSetFunction()

   Output Parameter:
.  f - function vector

   Note:
   The user-defined context can contain any application-specific
   data needed for the function evaluation.
*/
PetscErrorCode FormFunction(SNES snes,Vec x,Vec f,void *ctx)
{
  ApplicationCtx *user = (ApplicationCtx*) ctx;
  DA             da = user->da;
  PetscScalar    *xx,*ff,*FF,d;
  PetscErrorCode ierr;
  PetscInt       i,M,xs,xm;
  Vec            xlocal;

  PetscFunctionBegin;
  ierr = DAGetLocalVector(da,&xlocal);CHKERRQ(ierr);
  /*
     Scatter ghost points to local vector, using the 2-step process
        DAGlobalToLocalBegin(), DAGlobalToLocalEnd().
     By placing code between these two statements, computations can
     be done while messages are in transition.
  */
  ierr = DAGlobalToLocalBegin(da,x,INSERT_VALUES,xlocal);CHKERRQ(ierr);
  ierr = DAGlobalToLocalEnd(da,x,INSERT_VALUES,xlocal);CHKERRQ(ierr);

  /*
     Get pointers to vector data.
       - The vector xlocal includes ghost point; the vectors x and f do
         NOT include ghost points.
       - Using DAVecGetArray() allows accessing the values using global ordering
  */
  ierr = DAVecGetArray(da,xlocal,&xx);CHKERRQ(ierr);
  ierr = DAVecGetArray(da,f,&ff);CHKERRQ(ierr);
  ierr = DAVecGetArray(da,user->F,&FF);CHKERRQ(ierr);

  /*
     Get local grid boundaries (for 1-dimensional DA):
       xs, xm  - starting grid index, width of local grid (no ghost points)
  */
  ierr = DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
  ierr = DAGetInfo(da,PETSC_NULL,&M,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,
                   PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);

  /*
     Set function values for boundary points; define local interior grid point range:
        xsi - starting interior grid index
        xei - ending interior grid index
  */
  if (xs == 0) { /* left boundary */
    ff[0] = xx[0];
    xs++;xm--;
  }
  if (xs+xm == M) {  /* right boundary */
    ff[xs+xm-1] = xx[xs+xm-1] - 1.0;
    xm--;
  }

  /*
     Compute function over locally owned part of the grid (interior points only)
  */
  d = 1.0/(user->h*user->h);
  for (i=xs; i<xs+xm; i++) {
    ff[i] = d*(xx[i-1] - 2.0*xx[i] + xx[i+1]) + xx[i]*xx[i] - FF[i];
  }

  /*
     Restore vectors
  */
  ierr = DAVecRestoreArray(da,xlocal,&xx);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(da,f,&ff);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(da,user->F,&FF);CHKERRQ(ierr);
  ierr = DARestoreLocalVector(da,&xlocal);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Пример #22
0
int main(int argc,char **argv)
{
  PetscErrorCode         ierr;

  SNES                   snes;                 /* nonlinear solver */
  Vec                    Hu,r;                 /* solution, residual vectors */
  Mat                    J;                    /* Jacobian matrix */
  AppCtx                 user;                 /* user-defined work context */
  PetscInt               its, i, tmpxs, tmpxm; /* iteration count, index, etc. */
  PetscReal              tmp1, tmp2, tmp3, tmp4, tmp5,
                         errnorms[2], descaleNode[2];
  PetscTruth             eps_set = PETSC_FALSE, dump = PETSC_FALSE, exactinitial = PETSC_FALSE,
                         snes_mf_set, snes_fd_set;
  MatFDColoring          matfdcoloring = 0;
  ISColoring             iscoloring;
  SNESConvergedReason    reason;               /* Check convergence */
  
  PetscInitialize(&argc,&argv,(char *)0,help);
  ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &user.rank); CHKERRQ(ierr);

  ierr = PetscPrintf(PETSC_COMM_WORLD,
    "BODVARDSSON solves for thickness and velocity in 1D, steady ice stream\n"
    "  [run with -help for info and options]\n");CHKERRQ(ierr);

  user.n       = 3.0;          /* Glen flow law exponent */
  user.secpera = 31556926.0;
  user.rho     = 910.0;        /* kg m^-3 */
  user.rhow    = 1028.0;       /* kg m^-3 */
  user.g       = 9.81;         /* m s^-2 */
  
  /* ask Test N for its parameters, but only those we need to solve */
  ierr = params_exactN(&(user.H0), &tmp1, &(user.xc), &tmp2, &tmp3, &tmp4, &tmp5, 
                       &(user.Txc)); CHKERRQ(ierr);
  /* regularize using strain rate of 1/xc per year */
  user.epsilon = (1.0 / user.secpera) / user.xc;
  /* tools for non-dimensionalizing to improve equation scaling */
  user.scaleNode[0] = 1000.0;  user.scaleNode[1] = 100.0 / user.secpera;
  
  ierr = PetscOptionsTruth("-snes_mf","","",PETSC_FALSE,&snes_mf_set,NULL);CHKERRQ(ierr);
  ierr = PetscOptionsTruth("-snes_fd","","",PETSC_FALSE,&snes_fd_set,NULL);CHKERRQ(ierr);
  if (!snes_mf_set && !snes_fd_set) { 
    PetscPrintf(PETSC_COMM_WORLD,
       "\n***ERROR: bodvardsson needs one or zero of '-snes_mf', '-snes_fd'***\n\n"
       "USAGE FOLLOWS ...\n\n%s",help);
    PetscEnd();
  }

  if (snes_fd_set) {
    ierr = PetscPrintf(PETSC_COMM_WORLD,
       "  using approximate Jacobian; finite-differencing using coloring\n");
       CHKERRQ(ierr);
  } else if (snes_mf_set) {
    ierr = PetscPrintf(PETSC_COMM_WORLD,
       "  matrix free; no preconditioner\n"); CHKERRQ(ierr);
  } else {
    ierr = PetscPrintf(PETSC_COMM_WORLD,
       "  true Jacobian\n"); CHKERRQ(ierr);
  }

  ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,
      "bodvardsson program options",__FILE__);CHKERRQ(ierr);
  {
    ierr = PetscOptionsTruth("-bod_up_one","","",PETSC_FALSE,&user.upwind1,NULL);CHKERRQ(ierr);
    ierr = PetscOptionsTruth("-bod_exact_init","","",PETSC_FALSE,&exactinitial,NULL);CHKERRQ(ierr);
    ierr = PetscOptionsTruth("-bod_dump",
      "dump out exact and approximate solution and residual, as asci","",
      dump,&dump,NULL);CHKERRQ(ierr);
    ierr = PetscOptionsReal("-bod_epsilon","regularization (a strain rate in units of 1/a)","",
                            user.epsilon * user.secpera,&user.epsilon,&eps_set);CHKERRQ(ierr);
    if (eps_set)  user.epsilon *= 1.0 / user.secpera;
  }
  ierr = PetscOptionsEnd();CHKERRQ(ierr);

  /* Create machinery for parallel grid management (DA), nonlinear solver (SNES), 
     and Vecs for fields (solution, RHS).  Note default Mx=46 grid points means
     dx=10 km.  Also degrees of freedom = 2 (thickness and velocity
     at each point) and stencil radius = ghost width = 2 for 2nd-order upwinding.  */
  user.solnghostwidth = 2;
  ierr = DACreate1d(PETSC_COMM_WORLD,DA_NONPERIODIC,-46,2,user.solnghostwidth,PETSC_NULL,&user.da);
            CHKERRQ(ierr);
  ierr = DASetUniformCoordinates(user.da,0.0,user.xc,
                                 PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
  ierr = DASetFieldName(user.da,0,"ice thickness [non-dimensional]"); CHKERRQ(ierr);
  ierr = DASetFieldName(user.da,1,"ice velocity [non-dimensional]"); CHKERRQ(ierr);
  ierr = DAGetInfo(user.da,PETSC_IGNORE,&user.Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,
                   PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
  ierr = DAGetCorners(user.da,&user.xs,PETSC_NULL,PETSC_NULL,&user.xm,PETSC_NULL,PETSC_NULL);
                   CHKERRQ(ierr);
  user.dx = user.xc / (PetscReal)(user.Mx-1);

  /* another DA for scalar parameters, with same length */
  ierr = DACreate1d(PETSC_COMM_WORLD,DA_NONPERIODIC,user.Mx,1,1,PETSC_NULL,&user.scalarda);CHKERRQ(ierr);
  ierr = DASetUniformCoordinates(user.scalarda,0.0,user.xc,
                                 PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
  /* check that parallel layout of scalar DA is same as dof=2 DA */
  ierr = DAGetCorners(user.scalarda,&tmpxs,PETSC_NULL,PETSC_NULL,&tmpxm,PETSC_NULL,PETSC_NULL);
                   CHKERRQ(ierr);
  if ((tmpxs != user.xs) || (tmpxm != user.xm)) {
    PetscPrintf(PETSC_COMM_SELF,
       "\n***ERROR: rank %d gets different ownership range for the two DAs!  ENDING ...***\n\n",
       user.rank);
    PetscEnd();
  }

  ierr = PetscPrintf(PETSC_COMM_WORLD,
      "  Mx = %D points, dx = %.3f m\n  H0 = %.2f m, xc = %.2f km, Txc = %.5e Pa m\n",
      user.Mx, user.dx, user.H0, user.xc/1000.0, user.Txc);CHKERRQ(ierr);

  /* Extract/allocate global vectors from DAs and duplicate for remaining same types */
  ierr = DACreateGlobalVector(user.da,&Hu);CHKERRQ(ierr);
  ierr = VecSetBlockSize(Hu,2);CHKERRQ(ierr);
  ierr = VecDuplicate(Hu,&r);CHKERRQ(ierr); /* inherits block size */
  ierr = VecDuplicate(Hu,&user.Huexact);CHKERRQ(ierr); /* ditto */

  ierr = DACreateGlobalVector(user.scalarda,&user.M);CHKERRQ(ierr);
  ierr = VecDuplicate(user.M,&user.Bstag);CHKERRQ(ierr);
  ierr = VecDuplicate(user.M,&user.beta);CHKERRQ(ierr);

  ierr = DASetLocalFunction(user.da,(DALocalFunction1)scshell);CHKERRQ(ierr);
  ierr = DASetLocalJacobian(user.da,(DALocalFunction1)BodJacobianMatrixLocal);CHKERRQ(ierr);

  ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr);

  ierr = SNESSetFunction(snes,r,SNESDAFormFunction,&user);CHKERRQ(ierr);

  /* setting up a matrix is only actually needed for -snes_fd case */
  ierr = DAGetMatrix(user.da,MATAIJ,&J);CHKERRQ(ierr);

  if (snes_fd_set) {
    /* tools needed so DA can use sparse matrix for its F.D. Jacobian approx */
    ierr = DAGetColoring(user.da,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr);
    ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr);
    ierr = ISColoringDestroy(iscoloring);CHKERRQ(ierr);
    ierr = MatFDColoringSetFunction(matfdcoloring,
               (PetscErrorCode (*)(void))SNESDAFormFunction,&user);CHKERRQ(ierr);
    ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
    ierr = SNESSetJacobian(snes,J,J,SNESDefaultComputeJacobianColor,matfdcoloring);CHKERRQ(ierr);
  } else {
    ierr = SNESSetJacobian(snes,J,J,SNESDAComputeJacobian,&user);CHKERRQ(ierr);
  }

  ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);

  /* the the Bodvardsson (1955) exact solution allows setting M(x), B(x), beta(x), T(xc) */
  ierr = FillDistributedParams(&user);CHKERRQ(ierr);

  /* the exact thickness and exact ice velocity (user.uHexact) are known from Bodvardsson (1955) */
  ierr = FillExactSoln(&user); CHKERRQ(ierr);

  if (exactinitial) {
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  using exact solution as initial guess\n");
             CHKERRQ(ierr);
    /* the initial guess is the exact continuum solution */
    ierr = VecCopy(user.Huexact,Hu); CHKERRQ(ierr);
  } else {
    ierr = FillInitial(&user, &Hu); CHKERRQ(ierr);
  }
  
  /************ SOLVE NONLINEAR SYSTEM  ************/
  /* recall that RHS  r  is used internally by KSP, and is set by the SNES */
  for (i = 0; i < 2; i++)  descaleNode[i] = 1.0 / user.scaleNode[i];
  ierr = VecStrideScaleAll(Hu,descaleNode); CHKERRQ(ierr); /* de-dimensionalize initial guess */
  ierr = SNESSolve(snes,PETSC_NULL,Hu);CHKERRQ(ierr);
  ierr = VecStrideScaleAll(Hu,user.scaleNode); CHKERRQ(ierr); /* put back in "real" scale */

  ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
  ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,
           "  %s Number of Newton iterations = %D\n",
           SNESConvergedReasons[reason],its);CHKERRQ(ierr);

  if (dump) {
    ierr = PetscPrintf(PETSC_COMM_WORLD,
           "  viewing combined result Hu\n");CHKERRQ(ierr);
    ierr = VecView(Hu,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,
           "  viewing combined exact result Huexact\n");CHKERRQ(ierr);
    ierr = VecView(user.Huexact,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,
           "  viewing final combined residual at Hu\n");CHKERRQ(ierr);
    ierr = VecView(r,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr);
  }

  /* evaluate error relative to exact solution */
  ierr = VecAXPY(Hu,-1.0,user.Huexact); CHKERRQ(ierr);  /* Hu = - Huexact + Hu */
  ierr = VecStrideNormAll(Hu,NORM_INFINITY,errnorms); CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,
           "(dx,errHinf,erruinf) %.3f %.4e %.4e\n",
           user.dx,errnorms[0],errnorms[1]*user.secpera);CHKERRQ(ierr);

  ierr = VecDestroy(Hu);CHKERRQ(ierr);
  ierr = VecDestroy(r);CHKERRQ(ierr);
  ierr = VecDestroy(user.Huexact);CHKERRQ(ierr);
  ierr = VecDestroy(user.M);CHKERRQ(ierr);
  ierr = VecDestroy(user.Bstag);CHKERRQ(ierr);
  ierr = VecDestroy(user.beta);CHKERRQ(ierr);

  ierr = MatDestroy(J); CHKERRQ(ierr);

  ierr = SNESDestroy(snes);CHKERRQ(ierr);

  ierr = DADestroy(user.da);CHKERRQ(ierr);
  ierr = DADestroy(user.scalarda);CHKERRQ(ierr);

  ierr = PetscFinalize();CHKERRQ(ierr);
  return 0;
}
Пример #23
0
int main(int argc, char **argv)
{       
  PetscInitialize(&argc, &argv, "elas.opt", help);

  int rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);


  int Ns = 32;
  unsigned int dof = 3;

  char problemName[PETSC_MAX_PATH_LEN];
  char filename[PETSC_MAX_PATH_LEN];

  double t0 = 0.0;
  double dt = 0.1;
  double t1 = 1.0;
  double beta = 0.000001;
  double gamma = 0.0; // percent of noise added ...

  // double dtratio = 1.0;
  DA  da;         // Underlying scalar DA - for scalar properties
  DA  da3d;       // Underlying vector DA - for vector properties

  Vec rho;        // density - elemental scalar
  Vec lambda;     // Lame parameter - lambda - elemental scalar
  Vec mu;         // Lame parameter - mu - elemental scalar
  Vec fibers;     // Fiber orientations - nodal vector (3-dof)
  Vec fibersElemental; // for IO. will be destroyed. - elemental vector (3-dof)

  std::vector<Vec> tau;        // the scalar activation - nodal scalar

  // Initial conditions
  Vec initialDisplacement; 
  Vec initialVelocity;

  timeInfo ti;

  // get Ns
  CHKERRQ ( PetscOptionsGetInt(0,"-Ns",&Ns,0) );

  CHKERRQ ( PetscOptionsGetScalar(0,"-t0",&t0,0) );
  CHKERRQ ( PetscOptionsGetScalar(0,"-t1",&t1,0) );
  CHKERRQ ( PetscOptionsGetScalar(0,"-dt",&dt,0) );
  CHKERRQ ( PetscOptionsGetScalar(0,"-beta",&beta,0) );
  CHKERRQ ( PetscOptionsGetString(PETSC_NULL,"-pn",problemName,PETSC_MAX_PATH_LEN-1,PETSC_NULL));

   if (!rank) {
    std::cout << "Problem size is " << Ns+1 << " spatially and NT = " << (int)ceil(1.0/dt) << std::endl;
  }

  // Time info for timestepping
  ti.start = t0;
  ti.stop  = t1;
  ti.step  = dt;

  // create DA
  CHKERRQ ( DACreate3d ( PETSC_COMM_WORLD, DA_NONPERIODIC, DA_STENCIL_BOX, 
                    Ns+1, Ns+1, Ns+1, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE,
                    1, 1, 0, 0, 0, &da) );
  CHKERRQ ( DACreate3d ( PETSC_COMM_WORLD, DA_NONPERIODIC, DA_STENCIL_BOX, 
                    Ns+1, Ns+1, Ns+1, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE,
                    dof, 1, 0, 0, 0, &da3d) );

  elasMass *Mass = new elasMass(feMat::PETSC); // Mass Matrix
  elasStiffness *Stiffness = new elasStiffness(feMat::PETSC); // Stiffness matrix
  raleighDamping *Damping = new raleighDamping(feMat::PETSC); // Damping Matrix

  cardiacDynamic *Force = new cardiacDynamic(feVec::PETSC); // Force Vector

  // create vectors 
  CHKERRQ( DACreateGlobalVector(da, &rho) );
  CHKERRQ( DACreateGlobalVector(da, &mu) );
  CHKERRQ( DACreateGlobalVector(da, &lambda) );

  CHKERRQ( DACreateGlobalVector(da3d, &initialDisplacement) );
  CHKERRQ( DACreateGlobalVector(da3d, &initialVelocity) );

  // Set initial conditions
  CHKERRQ( VecSet ( initialDisplacement, 0.0) ); 
  CHKERRQ( VecSet ( initialVelocity, 0.0) );

  VecZeroEntries( mu );
  VecZeroEntries( lambda );
  VecZeroEntries( rho );

  int x, y, z, m, n, p;
  int mx,my,mz, xne, yne, zne;

  CHKERRQ( DAGetCorners(da, &x, &y, &z, &m, &n, &p) ); 
  CHKERRQ( DAGetInfo(da,0, &mx, &my, &mz, 0,0,0,0,0,0,0) ); 

  if (x+m == mx) {
    xne=m-1;
  } else {
    xne=m;
  }
  if (y+n == my) {
    yne=n-1;
  } else {
    yne=n;
  }
  if (z+p == mz) {
    zne=p-1;
  } else {
    zne=p;
  }

  double acx,acy,acz;
  double hx = 1.0/((double)Ns);

  // SET MATERIAL PROPERTIES ...

  // @todo - Write routines to read/write in Parallel
  // allocate for temporary buffers ...
  unsigned int elemSize = Ns*Ns*Ns;
  // std::cout << "Elem size is " << elemSize << std::endl;
  unsigned int nodeSize = (Ns+1)*(Ns+1)*(Ns+1);

  unsigned char *tmp_mat = new unsigned char[elemSize];  
  double *tmp_tau = new double[dof*elemSize];

  // generate filenames & read in the raw arrays first ...
  std::ifstream fin;

  sprintf(filename, "%s.%d.img", problemName, Ns); 
  fin.open(filename, std::ios::binary); fin.read((char *)tmp_mat, elemSize); fin.close();
  
  // Set Elemental material properties
  PetscScalar ***muArray, ***lambdaArray, ***rhoArray;

  CHKERRQ(DAVecGetArray(da, mu, &muArray));
  CHKERRQ(DAVecGetArray(da, lambda, &lambdaArray));
  CHKERRQ(DAVecGetArray(da, rho, &rhoArray));

  // assign material properties ...
  //       myo,   tissue
  // nu  = 0.49,  0.45
  // E   = 10000, 1000
  // rho = 1.0,   0.1

  // std::cout << "Setting Elemental properties." << std::endl;

  // loop through all elements ...
  for (int k=z; k<z+zne; k++) {
    for (int j=y; j<y+yne; j++) {
      for (int i=x; i<x+xne; i++) {
        int indx = k*Ns*Ns + j*Ns + i;

        if ( tmp_mat[indx] ) {
          muArray[k][j][i] = 344.82; //3355.7;
          lambdaArray[k][j][i] = 3103.448;// 164429.53;
          rhoArray[k][j][i] = 1.0;
        } else {
          muArray[k][j][i] = 344.82;
          lambdaArray[k][j][i] = 3103.448;
          rhoArray[k][j][i] = 1.0;
        }

      } // end i
    } // end j
  } // end k

  // std::cout << "Finished Elemental loop." << std::endl;

  CHKERRQ( DAVecRestoreArray ( da, mu, &muArray ) );
  CHKERRQ( DAVecRestoreArray ( da, lambda, &lambdaArray ) );
  CHKERRQ( DAVecRestoreArray ( da, rho, &rhoArray ) );

  // std::cout << "Finished restoring arrays" << std::endl; 
  // delete temporary buffers
  
  delete [] tmp_mat;
  
  // Now set the activation ...
  unsigned int numSteps = (unsigned int)(ceil(( ti.stop - ti.start)/ti.step));
  // tau = (Vec *) new char*[numSteps+1];

  // std::cout << "Numsteps is " << numSteps << std::endl;
  Vec tauVec, tmpTau;
  
  CHKERRQ( DACreateGlobalVector(da3d, &tmpTau) );

#ifdef __DEBUG__  
  if (!rank) {
    std::cout << x << ", " << y << ", " << z << " + " << xne << ", " << yne << ", " << zne << std::endl;
  }
#endif  

  PetscScalar ***tauArray;
  double tauNorm;
  for (unsigned int t=0; t<numSteps+1; t++) {
    CHKERRQ( DACreateGlobalVector(da3d, &tauVec) );
    CHKERRQ( VecSet( tmpTau, 0.0));

    CHKERRQ(DAVecGetArray(da3d, tmpTau, &tauArray));

    // std::cout << "Setting force vectors" << std::endl;
    sprintf(filename, "%s.%d.%.3d.fld", problemName, Ns, t);
    // std::cout << "Reading force file " << filename << std::endl;
    fin.open(filename); fin.read((char *)tmp_tau, dof*elemSize*sizeof(double)); fin.close();
    for (int k = z; k < z + zne ; k++) {
      for (int j = y; j < y + yne; j++) {
        for (int i = x; i < x + xne; i++) {
          int indx = dof*(k*Ns*Ns + j*Ns + i);
          tauArray[k][j][dof*i] = tmp_tau[indx];
          tauArray[k][j][dof*i+1] = tmp_tau[indx+1];
          tauArray[k][j][dof*i+2] = tmp_tau[indx+2];
        }
      }
    }
    // std::cout << CYN"\tFinished elemental loop"NRM << std::endl;
    CHKERRQ( DAVecRestoreArray ( da3d, tmpTau, &tauArray ) );
    // std::cout << "Converting to Nodal Vector" << std::endl;
    // VecNorm(tmpTau, NORM_2, &tauNorm);
    // tauNorm = tauNorm/pow(Ns,1.5);
    // std::cout << "Elemental Norm is " << tauNorm << std::endl;
    // std::cout << rank << " Converting to Nodal" << std::endl;
    elementToNode(da3d, tmpTau, tauVec);
    /*
    VecNorm(tauVec, NORM_2, &tauNorm);
    tauNorm = tauNorm/pow(Ns,1.5);
    std::cout << "Nodal Norm is " << tauNorm << std::endl;
    */

    // std::cout << rank << " Done converting to Nodal Vector" << std::endl;
    tau.push_back(tauVec);
  }
  //if (!rank) {
  //  std::cout << "Finished setting forces" << std::endl;
  // }

  // CHKERRQ( VecDestroy( tmpTau ) );
  delete [] tmp_tau;

  // DONE - SET MATERIAL PROPERTIES ...

  // Setup Matrices and Force Vector ...
  Mass->setProblemDimensions(1.0, 1.0, 1.0);
  Mass->setDA(da3d);
  Mass->setDof(dof);
  Mass->setDensity(rho);

  Stiffness->setProblemDimensions(1.0, 1.0, 1.0);
  Stiffness->setDA(da3d);
  Stiffness->setDof(dof);
  Stiffness->setLame(lambda, mu);

  Damping->setAlpha(0.0);
  Damping->setBeta(0.00075);
  Damping->setMassMatrix(Mass);
  Damping->setStiffnessMatrix(Stiffness);
  Damping->setDA(da3d);
  Damping->setDof(dof);

  // Force Vector
  Force->setProblemDimensions(1.0,1.0,1.0);
  Force->setDA(da3d);
  // Force->setActivationVec(tau);
  // Force->setFiberOrientations(fibers);
  Force->setFDynamic(tau);
  Force->setTimeInfo(&ti);

  // Newmark time stepper ...
  newmark *ts = new newmark; 

  ts->setMassMatrix(Mass);
  ts->setDampingMatrix(Damping);
  ts->setStiffnessMatrix(Stiffness);
  ts->damp(false);
  ts->setTimeFrames(1);

  ts->setForceVector(Force);

  ts->setInitialDisplacement(initialDisplacement);
  ts->setInitialVelocity(initialVelocity);
  ts->storeVec(true);
  ts->setTimeInfo(&ti);
  ts->setAdjoint(false); // set if adjoint or forward

  ts->init(); // initialize IMPORTANT 
  if (!rank)
    std::cout << RED"Starting Newmark Solve"NRM << std::endl;
  ts->solve();// solve 
  if (!rank)
    std::cout << GRN"Done Newmark"NRM << std::endl;


  std::vector<Vec> solvec = ts->getSolution();

  /* Set very initial guess for the inverse problem*/
  /*
  PetscRandom rctx;
  PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
  PetscRandomSetFromOptions(rctx);
  VecSetRandom(guess,rctx);
  VecNorm(guess,NORM_INFINITY,&norm);
  PetscPrintf(0,"guess norm = %g\n",norm);
  */

  double errnorm;
  double exsolnorm;

  Vec guess;
  Vec truth;
  Vec Err;
  concatenateVecs(solvec, guess);
  concatenateVecs(tau, truth);
  
  iC(VecNorm(truth, NORM_2, &exsolnorm));

  /*
  std::cout << "Forward solver solution size is " << solvec.size() << std::endl;
  std::cout << "Forward solver solution norm is " << exsolnorm << std::endl;
*/
  VecZeroEntries(guess);

  // Inverse solver set up
  hyperbolicInverse *hyperInv = new hyperbolicInverse;

  hyperInv->setForwardInitialConditions(initialDisplacement, initialVelocity);
  hyperInv->setTimeStepper(ts);    // set the timestepper
  hyperInv->setInitialGuess(guess);// set the initial guess 
  // hyperInv->setInitialGuess(truth);// set the initial guess 
  hyperInv->setRegularizationParameter(beta); // set the regularization paramter
  hyperInv->setObservations(solvec); // set the data for the problem 
  hyperInv->init(); // initialize the inverse solver
  hyperInv->solve(); // solve
  hyperInv->getCurrentControl(guess); // get the solution 



  // see the error in the solution relative to the actual solution
  VecDuplicate(truth, &Err);
  iC(VecZeroEntries(Err)); 
  iC(VecWAXPY(Err, -1.0, guess, truth));
  iC(VecNorm(Err, NORM_2, &errnorm));
  PetscPrintf(0,"errr in inverse = %g\n", errnorm/exsolnorm);

  PetscFinalize();
}
Пример #24
0
/* Compute production variables, update Observations vector */
extern PetscErrorCode DefiantBlackOil3PhProduction(BlackOilReservoirSimulation* MySim)
{
  PetscErrorCode ierr;
  PetscInt mx, my, mz, xm, ym, zm, xs, ys, zs;
  /* Well handling variables */
  PetscInt PerfIDMine, WellID;

  PetscFunctionBegin;
  /* Get dimensions and extents of the local vectors */
  ierr = DAGetInfo(MySim->SimDA, 0, &mx, &my, &mz, 0, 0, 0, 0, 0, 0, 0);CHKERRQ(ierr);
  ierr = DAGetCorners(MySim->SimDA, &xs, &ys, &zs, &xm, &ym, &zm);CHKERRQ(ierr);
  /* Sync everything before we start */
  ierr = DefiantBlackOilComputePerfIndicesSyncPerfs(MySim);CHKERRQ(ierr);

  for (WellID = 0; WellID < MySim->NumberOfWells; WellID++) {
    for (PerfIDMine = 0; PerfIDMine
        < (MySim->Wells[WellID]).NumberOfPerforations; PerfIDMine++) {
      if (MySim->Wells[WellID].Perforations[PerfIDMine].IsActive == PETSC_TRUE ){
        if (MySim->Wells[WellID].Perforations[PerfIDMine].Constraint == FLOW_RATE_CONSTRAINT) {
          MySim->Wells[WellID].Perforations[PerfIDMine].BHPo =
              MySim->Wells[WellID].Perforations[PerfIDMine].Bo
            / (MySim->Wells[WellID].Perforations[PerfIDMine].h1
            * MySim->Wells[WellID].Perforations[PerfIDMine].h2
            * MySim->Wells[WellID].Perforations[PerfIDMine].h3)
            * MySim->Wells[WellID].Perforations[PerfIDMine].Muo
            / MySim->Wells[WellID].Perforations[PerfIDMine].Kro
            / MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex
            + MySim->Wells[WellID].Perforations[PerfIDMine].Po
            + MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhoo
            * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh
            - MySim->Wells[WellID].Perforations[PerfIDMine].x3);
          MySim->Wells[WellID].Perforations[PerfIDMine].BHPw =
              MySim->Wells[WellID].Perforations[PerfIDMine].Bw
            / (MySim->Wells[WellID].Perforations[PerfIDMine].h1
            * MySim->Wells[WellID].Perforations[PerfIDMine].h2
            * MySim->Wells[WellID].Perforations[PerfIDMine].h3)
            * MySim->Wells[WellID].Perforations[PerfIDMine].Muw
            / MySim->Wells[WellID].Perforations[PerfIDMine].Krw
            / MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex
            + MySim->Wells[WellID].Perforations[PerfIDMine].Pw
            + MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhow
            * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh
            - MySim->Wells[WellID].Perforations[PerfIDMine].x3);
          MySim->Wells[WellID].Perforations[PerfIDMine].BHPg =
              MySim->Wells[WellID].Perforations[PerfIDMine].Bg
            / (MySim->Wells[WellID].Perforations[PerfIDMine].h1
            * MySim->Wells[WellID].Perforations[PerfIDMine].h2
            * MySim->Wells[WellID].Perforations[PerfIDMine].h3)
            * MySim->Wells[WellID].Perforations[PerfIDMine].Mug
            / MySim->Wells[WellID].Perforations[PerfIDMine].Krg
            / MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex
            + MySim->Wells[WellID].Perforations[PerfIDMine].Pg
            + MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhog
            * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh
            - MySim->Wells[WellID].Perforations[PerfIDMine].x3);
        } else if (MySim->Wells[WellID].Perforations[PerfIDMine].Constraint == BHP_CONSTRAINT) {
          MySim->Wells[WellID].Perforations[PerfIDMine].Qo =
                MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex
              * MySim->Wells[WellID].Perforations[PerfIDMine].Kro
              / MySim->Wells[WellID].Perforations[PerfIDMine].Muo
              * (MySim->Wells[WellID].Perforations[PerfIDMine].BHPo
              - MySim->Wells[WellID].Perforations[PerfIDMine].Po
              - MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhoo
              * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh
              - MySim->Wells[WellID].Perforations[PerfIDMine].x3))
              * MySim->Wells[WellID].Perforations[PerfIDMine].h1
              * MySim->Wells[WellID].Perforations[PerfIDMine].h2
              * MySim->Wells[WellID].Perforations[PerfIDMine].h3
              / MySim->Wells[WellID].Perforations[PerfIDMine].Bo;
          MySim->Wells[WellID].Perforations[PerfIDMine].Qw =
                MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex
              * MySim->Wells[WellID].Perforations[PerfIDMine].Krw
              / MySim->Wells[WellID].Perforations[PerfIDMine].Muw
              * (MySim->Wells[WellID].Perforations[PerfIDMine].BHPw
              - MySim->Wells[WellID].Perforations[PerfIDMine].Pw
              - MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhow
              * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh
              - MySim->Wells[WellID].Perforations[PerfIDMine].x3))
              * MySim->Wells[WellID].Perforations[PerfIDMine].h1
              * MySim->Wells[WellID].Perforations[PerfIDMine].h2
              * MySim->Wells[WellID].Perforations[PerfIDMine].h3
              / MySim->Wells[WellID].Perforations[PerfIDMine].Bw;
          MySim->Wells[WellID].Perforations[PerfIDMine].Qg =
                MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex
              * MySim->Wells[WellID].Perforations[PerfIDMine].Krg
              / MySim->Wells[WellID].Perforations[PerfIDMine].Mug
              * (MySim->Wells[WellID].Perforations[PerfIDMine].BHPg
              - MySim->Wells[WellID].Perforations[PerfIDMine].Pg
              - MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhog
              * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh
              - MySim->Wells[WellID].Perforations[PerfIDMine].x3))
              * MySim->Wells[WellID].Perforations[PerfIDMine].h1
              * MySim->Wells[WellID].Perforations[PerfIDMine].h2
              * MySim->Wells[WellID].Perforations[PerfIDMine].h3
              / MySim->Wells[WellID].Perforations[PerfIDMine].Bg;
        }
      }
    }
  }


  PetscFunctionReturn(0);
}
Пример #25
0
/*
   FormJacobian - Evaluates Jacobian matrix.

   Input Parameters:
.  snes - the SNES context
.  x - input vector
.  dummy - optional user-defined context (not used here)

   Output Parameters:
.  jac - Jacobian matrix
.  B - optionally different preconditioning matrix
.  flag - flag indicating matrix structure
*/
PetscErrorCode FormJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure*flag,void *ctx)
{
  ApplicationCtx *user = (ApplicationCtx*) ctx;
  PetscScalar    *xx,d,A[3];
  PetscErrorCode ierr;           
  PetscInt       i,j[3],M,xs,xm;
  DA             da = user->da;

  PetscFunctionBegin;
  /*
     Get pointer to vector data
  */
  ierr = DAVecGetArray(da,x,&xx);CHKERRQ(ierr);
  ierr = DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);

  /*
    Get range of locally owned matrix
  */
  ierr = DAGetInfo(da,PETSC_NULL,&M,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,
                   PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);

  /*
     Determine starting and ending local indices for interior grid points.
     Set Jacobian entries for boundary points.
  */

  if (xs == 0) {  /* left boundary */
    i = 0; A[0] = 1.0; 
    ierr = MatSetValues(*jac,1,&i,1,&i,A,INSERT_VALUES);CHKERRQ(ierr);
    xs++;xm--;
  }
  if (xs+xm == M) { /* right boundary */
    i = M-1; A[0] = 1.0; 
    ierr = MatSetValues(*jac,1,&i,1,&i,A,INSERT_VALUES);CHKERRQ(ierr);
    xm--;
  }

  /*
     Interior grid points
      - Note that in this case we set all elements for a particular
        row at once.
  */
  d = 1.0/(user->h*user->h);
  for (i=xs; i<xs+xm; i++) {
    j[0] = i - 1; j[1] = i; j[2] = i + 1; 
    A[0] = A[2] = d; A[1] = -2.0*d + 2.0*xx[i];
    ierr = MatSetValues(*jac,1,&i,3,j,A,INSERT_VALUES);CHKERRQ(ierr);
  }

  /* 
     Assemble matrix, using the 2-step process:
       MatAssemblyBegin(), MatAssemblyEnd().
     By placing code between these two statements, computations can be
     done while messages are in transition.

     Also, restore vector.
  */

  ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(da,x,&xx);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

  *flag = SAME_NONZERO_PATTERN;
  PetscFunctionReturn(0);
}
Пример #26
0
PetscErrorCode vizGA2DA()
{
  PetscErrorCode  ierr;
  int rank;
  MPI_Comm_rank(PETSC_COMM_WORLD,&rank);  
  int d1 = 40, d2 = 50;
  
  DA da;
  Vec vec;
  const PetscInt *lx, *ly, *lz;
  PetscInt m,n,p;
  DALocalInfo info;
  ierr = DACreate2d(PETSC_COMM_WORLD,DA_NONPERIODIC,DA_STENCIL_STAR,
            d1,d2,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0, &da); CHKERRQ(ierr);
  ierr = DACreateGlobalVector(da, &vec); CHKERRQ(ierr);
  ierr = DAGetOwnershipRanges(da, &lx, &ly, &lz); CHKERRQ(ierr);
  ierr = DAGetLocalInfo(da,&info); CHKERRQ(ierr);
  ierr = DAGetInfo(da,0,0,0,0,&m,&n,&p,0,0,0,0); CHKERRQ(ierr);
  /**/
  ierr = DAView(da, PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr);
  for (int i = 0; i < m; ++i) {
    PetscPrintf(PETSC_COMM_WORLD,"%d\tlx: %d\n",i,lx[i]);
  }
  for (int i = 0; i < n; ++i) {
    PetscPrintf(PETSC_COMM_WORLD,"%d\tly: %d\n",i,ly[i]);
  }
  /**/
 
  
  int ga = GA_Create_handle();
  int ndim = 2;
  int dims[2] = {d2,d1};
  GA_Set_data(ga,2,dims,MT_DBL);
  int *map;
  PetscMalloc( sizeof(int)*(m+n), &map);
  map[0] = 0;
  for( int i = 1; i < n; i++ )
  {
    map[i] = ly[i-1] + map[i-1];
  }
  map[n] = 0;
  for( int i = n+1; i < m+n; i++ )
  {
    map[i] = lx[i-n-1] + map[i-1];
  }
  /* correct ordering, but nodeid's dont line up with mpi rank for petsc's da
   * DA: +---+---+   GA: +---+---+   
   *     +-2-+-3-+       +-1-+-3-+
   *     +---+---+       +---+---+
   *     +-0-+-1-+       +-0-+-2-+
   *     +---+---+       +---+---+
  int *map;
  PetscMalloc( sizeof(int)*(m+n), &map);
  map[0] = 0;
  for( int i = 1; i < m; i++ )
  {
    map[i] = lx[i] + map[i-1];
  }
  map[m] = 0;
  for( int i = m+1; i < m+n; i++ )
  {
    map[i] = ly[i-m] + map[i-1];
  }
  */
  int block[2] = {n,m};  
  GA_Set_irreg_distr(ga,map,block);
  ierr = GA_Allocate( ga );
  if( !ierr ) GA_Error("\n\n\nga allocaltion failed\n\n",ierr);
  if( !ga ) GA_Error("\n\n\n ga null \n\n",ierr); 
  if( rank != GA_Nodeid() ) GA_Error("MPI rank does not match GA_Nodeid()",1);
  GA_Print_distribution(ga);  
  
  int lo[2], hi[2];
  NGA_Distribution(ga,rank,lo,hi);
  if( lo[1] != info.xs || hi[1] != info.xs+info.xm-1 ||
      lo[0] != info.ys || hi[0] != info.ys+info.ym-1 )
  {
    PetscSynchronizedPrintf(PETSC_COMM_SELF,"[%d] lo:(%2d,%2d)  hi:(%2d,%2d) \t DA: (%2d,%2d), (%2d, %2d)\n",
        rank, lo[1], lo[0], hi[1], hi[0], info.xs, info.ys, info.xs+info.xm-1, info.ys+info.ym-1);
  }
  PetscBarrier(0);
  PetscSynchronizedFlush(PETSC_COMM_WORLD);

  AO ao;
  DAGetAO(da,&ao);
  if( rank == 0 )
  {
    int *idx, len = d1*d2;
    PetscReal *val;
    PetscMalloc(sizeof(PetscReal)*len, &val);
    PetscMalloc(sizeof(int)*len, &idx);
    for (int j = 0; j < d2; ++j)
    {
      for (int i = 0; i < d1; ++i)
      {
        idx[i + d1*j] = i + d1*j;
        val[i + d1*j] = i + d1*j;
      }
    }
    AOApplicationToPetsc(ao,len,idx);
    VecSetValues(vec,len,idx,val,INSERT_VALUES);

    int a[2], b[2],ld[1]={0};
    double c = 0;
    for (int j = 0; j < d2; ++j)
    {
      for (int i = 0; i < d1; ++i)
      {
        a[0] = j;
        a[1] = i;
//        printf("%5.0f ",c);
        NGA_Put(ga,a,a,&c,ld);
        c++;
      }
    }
  }
//  GA_Print(ga);
  VecAssemblyBegin(vec);
  VecAssemblyEnd(vec);
  
  int ld;
  double *ptr;
  NGA_Access(ga,lo,hi,&ptr,&ld);
  PetscReal **d;
  int c=0;
  ierr = DAVecGetArray(da,vec,&d); CHKERRQ(ierr);
  for (int j = info.ys; j < info.ys+info.ym; ++j)
  {
    for (int i = info.xs; i < info.xs+info.xm; ++i)
    {
      if( d[j][i] != ptr[(i-info.xs)+ld*(j-info.ys)] )
        GA_Error("DA array is not equal to GA array",1);
//      printf("%d (%d,%d):\t%3.0f\t%3.0f\n", c, i, j, d[j][i], ptr[(i-info.xs)+ld*(j-info.ys)]);
      c++;
    }
  }
  ierr = DAVecRestoreArray(da,vec,&d); CHKERRQ(ierr);
  
  c=0;
  PetscReal *v;
  int start, end;
  VecGetOwnershipRange(vec, &start, &end);
  VecGetArray( vec, &v );
  for( int i = start; i < end; i++)
  {
//    printf("%d:\t%3.0f\t%3.0f\t%s\n", start, v[i-start], ptr[i-start], (v[i-start]-ptr[i-start]==0?"":"NO") );
  }
  VecRestoreArray( vec, &v );
  
  NGA_Release_update(ga,lo,hi);

  Vec gada;
  VecCreateMPIWithArray(((PetscObject)da)->comm,da->Nlocal,PETSC_DETERMINE,ptr,&gada);
  VecView(gada,PETSC_VIEWER_STDOUT_SELF);
  
  GA_Destroy(ga);
  
  
  
  ierr = VecDestroy(vec); CHKERRQ(ierr);
  ierr = DADestroy(da); CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Пример #27
0
extern PetscErrorCode DefiantBlackOilSyncPerfOwners(BlackOilReservoirSimulation* MySim)
{
  PetscErrorCode ierr;
  PetscInt i, rank, TotalNumberOfPerfs;
  PetscInt mx, my, mz, xm, ym, zm, xs, ys, zs;
  /* Well handling variables */
  PetscInt PerfIDMine, WellID;
  PetscInt MyI, MyJ, MyK;
  /* temporary array */
  PetscInt *InBuffer, *OutBuffer;

  PetscFunctionBegin;
  /* Get dimensions and extents of the local vectors */
  ierr = DAGetInfo(MySim->SimDA, 0, &mx, &my, &mz, 0, 0, 0, 0, 0, 0, 0);CHKERRQ(ierr);
  ierr = DAGetCorners(MySim->SimDA, &xs, &ys, &zs, &xm, &ym, &zm);CHKERRQ(ierr);
  /* Get the current rank */
  ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);CHKMEMQ;

  /* Allocate memory to the in and out Buffers */
  /* Find the total number of perforations */
  TotalNumberOfPerfs = 0;
  for (WellID = 0; WellID < MySim->NumberOfWells; WellID++)
      for (PerfIDMine = 0; PerfIDMine < (MySim->Wells[WellID]).NumberOfPerforations; PerfIDMine++)
        TotalNumberOfPerfs++;
  /* Allocate the In and out Buffers */
  ierr = PetscMalloc(sizeof(PetscInt)*TotalNumberOfPerfs, &InBuffer);CHKERRQ(ierr);CHKMEMQ;
  ierr = PetscMalloc(sizeof(PetscInt)*TotalNumberOfPerfs, &OutBuffer);CHKERRQ(ierr);CHKMEMQ;

  /* Pack all the perf owner location int the in buffer */
  i = 0;
  for (WellID = 0; WellID < MySim->NumberOfWells; WellID++) {
    for (PerfIDMine = 0; PerfIDMine
        < (MySim->Wells[WellID]).NumberOfPerforations; PerfIDMine++) {

      MyI = (MySim->Wells[WellID]).Perforations[PerfIDMine].I;CHKMEMQ;
      MyJ = (MySim->Wells[WellID]).Perforations[PerfIDMine].J;CHKMEMQ;
      MyK = (MySim->Wells[WellID]).Perforations[PerfIDMine].K;CHKMEMQ;

      if (MyI >= xs && MyI < xs+xm && MyJ >= ys && MyJ < ys+ym && MyK >= zs && MyK < zs+zm)
        MySim->Wells[WellID].Perforations[PerfIDMine].OwnerRank = rank;
      else
        MySim->Wells[WellID].Perforations[PerfIDMine].OwnerRank = -1;

      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].OwnerRank;
      i++;
    }
  }

  /* Make the syncrhonization call */
  ierr = MPI_Allreduce(InBuffer, OutBuffer, TotalNumberOfPerfs, MPI_INT, MPI_MAX, PETSC_COMM_WORLD);CHKERRQ(ierr);CHKMEMQ;

  /* Now unpack all the perf owner location int the in buffer */
  i = 0;
  for (WellID = 0; WellID < MySim->NumberOfWells; WellID++) {
    for (PerfIDMine = 0; PerfIDMine
        < (MySim->Wells[WellID]).NumberOfPerforations; PerfIDMine++) {

       MySim->Wells[WellID].Perforations[PerfIDMine].OwnerRank = OutBuffer[i];
       i++;
    }
  }

  PetscFunctionReturn(0);
}
Пример #28
0
int main(int argc,char **argv)
/*-----------------------------------------------------------------------*/
{
    DMMG           *dmmg;               /* multilevel grid structure */
    AppCtx         *user;               /* user-defined work context */
    Parameter      *param;
    GridInfo       grid;
    int            ierr,result;
    MPI_Comm       comm;
    DA             da;

    PetscInitialize(&argc,&argv,(char *)0,help);
    comm = PETSC_COMM_WORLD;

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Set up the problem parameters.
       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = PetscMalloc(sizeof(AppCtx),&user);
    CHKERRQ(ierr);
    ierr = PetscBagCreate(comm,sizeof(Parameter),&(user->bag));
    CHKERRQ(ierr);
    user->grid    = &grid;
    ierr = SetParams(user);
    CHKERRQ(ierr);
    ierr = ReportParams(user);
    CHKERRQ(ierr);
    ierr = PetscBagGetData(user->bag,(void**)&param);
    CHKERRQ(ierr);

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Create distributed array multigrid object (DMMG) to manage parallel grid and vectors
       for principal unknowns (x) and governing residuals (f)
       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = DMMGCreate(comm,grid.mglevels,user,&dmmg);
    CHKERRQ(ierr);
    ierr = DACreate2d(comm,grid.periodic,grid.stencil,grid.ni,grid.nj,PETSC_DECIDE,PETSC_DECIDE,grid.dof,grid.stencil_width,0,0,&da);
    CHKERRQ(ierr);
    ierr = DMMGSetDM(dmmg,(DM)da);
    CHKERRQ(ierr);
    ierr = DADestroy(da);
    CHKERRQ(ierr);
    ierr = DAGetInfo(da,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,&(param->pi),&(param->pj),PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL);
    CHKERRQ(ierr);
    REG_INTG(user->bag,&param->pi,param->pi ,"procs_x","<DO NOT SET> Processors in the x-direction");
    REG_INTG(user->bag,&param->pj,param->pj ,"procs_y","<DO NOT SET> Processors in the y-direction");

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Create user context, set problem data, create vector data structures.
       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = DAGetGlobalVector(da, &(user->Xold));
    CHKERRQ(ierr);

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Initialize and solve the nonlinear system
       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = Initialize(dmmg);
    CHKERRQ(ierr);
    ierr = DoSolve(dmmg);
    CHKERRQ(ierr);
    if (param->verify) result = param->verify_result;

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Free work space.
       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = DARestoreGlobalVector(da, &(user->Xold));
    CHKERRQ(ierr);
    ierr = PetscBagDestroy(user->bag);
    CHKERRQ(ierr);
    ierr = PetscFree(user);
    CHKERRQ(ierr);
    ierr = DMMGDestroy(dmmg);
    CHKERRQ(ierr);
    ierr = PetscFinalize();
    CHKERRQ(ierr);
    return result;
}
Пример #29
0
extern PetscErrorCode DefiantBlackOilComputePerfIndicesSyncPerfs(BlackOilReservoirSimulation* MySim)
{
  PetscErrorCode ierr;
  PetscInt mx, my, mz, xm, ym, zm, xs, ys, zs;
  PetscInt i, rank;
  /* Well handling variables */
  PetscInt PerfIDMine, WellID;
  PetscInt MyI, MyJ, MyK;
  PetscScalar re;
  /* Local values for variables*/
  PetscScalar ***Localx1,   ***Localx2,   ***Localx3;
  PetscScalar ***Localh1,   ***Localh2,   ***Localh3;
  PetscScalar ***LocalSo,   ***LocalSw,   ***LocalSg;
  PetscScalar ***LocalPo,   ***LocalPw,   ***LocalPg;
  PetscScalar ***LocalMuo,  ***LocalMuw,  ***LocalMug;
  PetscScalar ***LocalRhoo, ***LocalRhow, ***LocalRhog;
  PetscScalar ***LocalK11,  ***LocalK22,  ***LocalK33;
  PetscScalar ***LocalKro,  ***LocalKrw,  ***LocalKrg;
  PetscScalar ***LocalBo,   ***LocalBw,    ***LocalBg;
  PetscScalar ***LocalPcow, ***LocalPcog;
  /* temporary array */
  PetscScalar *InBuffer;

  PetscFunctionBegin;
  /* Allocate the In and out Buffers, we have 27 doubles at each perforation */
  ierr = PetscMalloc(sizeof(PetscScalar)*27, &InBuffer);CHKERRQ(ierr);CHKMEMQ;

  /* Get dimensions and extents of the local vectors */
  ierr = DAGetInfo(MySim->SimDA, 0, &mx, &my, &mz, 0, 0, 0, 0, 0, 0, 0);CHKERRQ(ierr);
  ierr = DAGetCorners(MySim->SimDA, &xs, &ys, &zs, &xm, &ym, &zm);CHKERRQ(ierr);
  /* Grab the local coordiantes */
  ierr = DAVecGetArray(MySim->SimDA, MySim->x1, &Localx1);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->x2, &Localx2);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->x3, &Localx3);CHKERRQ(ierr);CHKMEMQ;
  /* Grab the local geometry */
  ierr = DAVecGetArray(MySim->SimDA, MySim->h1, &Localh1);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->h2, &Localh2);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->h3, &Localh3);CHKERRQ(ierr);CHKMEMQ;
  /* Grab the Saturations */
  ierr = DAVecGetArray(MySim->SimDA, MySim->So, &LocalSo);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Sw, &LocalSw);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Sg, &LocalSg);CHKERRQ(ierr);CHKMEMQ;
  /* Grab the Pressures */
  ierr = DAVecGetArray(MySim->SimDA, MySim->Po, &LocalPo);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Pw, &LocalPw);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Pg, &LocalPg);CHKERRQ(ierr);CHKMEMQ;
  /* Grab the Densities */
  ierr = DAVecGetArray(MySim->SimDA, MySim->Rhoo, &LocalRhoo);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Rhow, &LocalRhow);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Rhog, &LocalRhog);CHKERRQ(ierr);CHKMEMQ;
  /* Grab the local viscosities*/
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muo, &LocalMuo);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Muw, &LocalMuw);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Mug, &LocalMug);CHKERRQ(ierr);CHKMEMQ;
  /* Grab the local permeabilities */
  ierr = DAVecGetArray(MySim->SimDA, MySim->K11, &LocalK11);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->K22, &LocalK22);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->K33, &LocalK33);CHKERRQ(ierr);CHKMEMQ;
  /* Grab the local permeabilities */
  ierr = DAVecGetArray(MySim->SimDA, MySim->Kro, &LocalKro);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Krw, &LocalKrw);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Krg, &LocalKrg);CHKERRQ(ierr);CHKMEMQ;
  /* Grab the local capillary pressure */
  ierr = DAVecGetArray(MySim->SimDA, MySim->Pcow, &LocalPcow);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Pcog, &LocalPcog);CHKERRQ(ierr);CHKMEMQ;
  /* Grab the local data for volume factors at the cell centers */
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bo, &LocalBo);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bw, &LocalBw);CHKERRQ(ierr);CHKMEMQ;
  ierr = DAVecGetArray(MySim->SimDA, MySim->Bg, &LocalBg);CHKERRQ(ierr);CHKMEMQ;

  /* Get the current rank */
  ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);CHKMEMQ;
  /* Now we sync all the flow rates and BHP's across all perforations */
  /* At the end of this loop, all information across all wells is uniform and up-to-date */
  for (WellID = 0; WellID < MySim->NumberOfWells; WellID++) {
    for (PerfIDMine = 0; PerfIDMine
        < (MySim->Wells[WellID]).NumberOfPerforations; PerfIDMine++) {

      MyI = (MySim->Wells[WellID]).Perforations[PerfIDMine].I;CHKMEMQ;
      MyJ = (MySim->Wells[WellID]).Perforations[PerfIDMine].J;CHKMEMQ;
      MyK = (MySim->Wells[WellID]).Perforations[PerfIDMine].K;CHKMEMQ;

      if (MyI >= xs && MyI < xs+xm && MyJ >= ys && MyJ < ys+ym && MyK >= zs && MyK < zs+zm)
      {
        MySim->Wells[WellID].Perforations[PerfIDMine].So = LocalSo[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Sw = LocalSw[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Sg = LocalSg[MyK][MyJ][MyI];CHKMEMQ;

        MySim->Wells[WellID].Perforations[PerfIDMine].Po = LocalPo[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Pw = LocalPw[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Pg = LocalPg[MyK][MyJ][MyI];CHKMEMQ;

        MySim->Wells[WellID].Perforations[PerfIDMine].Kro = LocalKro[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Krw = LocalKrw[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Krg = LocalKrg[MyK][MyJ][MyI];CHKMEMQ;

        MySim->Wells[WellID].Perforations[PerfIDMine].Muo = LocalMuo[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Muw = LocalMuw[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Mug = LocalMug[MyK][MyJ][MyI];CHKMEMQ;

        MySim->Wells[WellID].Perforations[PerfIDMine].Rhoo = LocalRhoo[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Rhow = LocalRhow[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Rhog = LocalRhog[MyK][MyJ][MyI];CHKMEMQ;

        MySim->Wells[WellID].Perforations[PerfIDMine].Pcow = LocalPcow[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Pcog = LocalPcog[MyK][MyJ][MyI];CHKMEMQ;

        MySim->Wells[WellID].Perforations[PerfIDMine].Bo = LocalBo[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Bw = LocalBw[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].Bg = LocalBg[MyK][MyJ][MyI];CHKMEMQ;

        MySim->Wells[WellID].Perforations[PerfIDMine].x1 = Localx1[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].x2 = Localx2[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].x3 = Localx3[MyK][MyJ][MyI];CHKMEMQ;

        MySim->Wells[WellID].Perforations[PerfIDMine].h1 = Localh1[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].h2 = Localh2[MyK][MyJ][MyI];CHKMEMQ;
        MySim->Wells[WellID].Perforations[PerfIDMine].h3 = Localh3[MyK][MyJ][MyI];CHKMEMQ;

        /* we also compute the well indices */
        if ((MySim->Wells[WellID]).Perforations[PerfIDMine].Orientation
            == PERF_ORIENTATION_X1X1) {
          re = 0.14 / 0.5 * sqrt((sqrt(LocalK33[MyK][MyJ][MyI]
              / LocalK22[MyK][MyJ][MyI]) * Localh2[MyK][MyJ][MyI]
              * Localh2[MyK][MyJ][MyI] + sqrt(LocalK22[MyK][MyJ][MyI]
              / LocalK33[MyK][MyJ][MyI]) * Localh3[MyK][MyJ][MyI]
              * Localh3[MyK][MyJ][MyI])) / (pow(LocalK33[MyK][MyJ][MyI]
              / LocalK22[MyK][MyJ][MyI], 0.25) + pow(LocalK22[MyK][MyJ][MyI]
              / LocalK33[MyK][MyJ][MyI], 0.25));
          MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex = 2.0 * PI
              * Localh1[MyK][MyJ][MyI] * sqrt(LocalK11[MyK][MyJ][MyI]
              * LocalK33[MyK][MyJ][MyI]) / (log(re
              / MySim->Wells[WellID].Perforations[PerfIDMine].Rw)
              + MySim->Wells[WellID].Perforations[PerfIDMine].S);
        } else if ((MySim->Wells[WellID]).Perforations[PerfIDMine].Orientation
            == PERF_ORIENTATION_X2X2) {
          re = 0.14 / 0.5 * sqrt((sqrt(LocalK33[MyK][MyJ][MyI]
              / LocalK11[MyK][MyJ][MyI]) * Localh1[MyK][MyJ][MyI]
              * Localh1[MyK][MyJ][MyI] + sqrt(LocalK11[MyK][MyJ][MyI]
              / LocalK33[MyK][MyJ][MyI]) * Localh3[MyK][MyJ][MyI]
              * Localh3[MyK][MyJ][MyI])) / (pow(LocalK33[MyK][MyJ][MyI]
              / LocalK11[MyK][MyJ][MyI], 0.25) + pow(LocalK11[MyK][MyJ][MyI]
              / LocalK33[MyK][MyJ][MyI], 0.25));
          MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex = 2.0 * PI
              * Localh2[MyK][MyJ][MyI] * sqrt(LocalK11[MyK][MyJ][MyI]
              * LocalK33[MyK][MyJ][MyI]) / (log(re
              / MySim->Wells[WellID].Perforations[PerfIDMine].Rw)
              + MySim->Wells[WellID].Perforations[PerfIDMine].S);
        } else if ((MySim->Wells[WellID]).Perforations[PerfIDMine].Orientation
            == PERF_ORIENTATION_X3X3) {
          re = 0.14 / 0.5 * sqrt((sqrt(LocalK22[MyK][MyJ][MyI]
              / LocalK11[MyK][MyJ][MyI]) * Localh1[MyK][MyJ][MyI]
              * Localh1[MyK][MyJ][MyI] + sqrt(LocalK11[MyK][MyJ][MyI]
              / LocalK22[MyK][MyJ][MyI]) * Localh2[MyK][MyJ][MyI]
              * Localh2[MyK][MyJ][MyI])) / (pow(LocalK22[MyK][MyJ][MyI]
              / LocalK11[MyK][MyJ][MyI], 0.25) + pow(LocalK11[MyK][MyJ][MyI]
              / LocalK22[MyK][MyJ][MyI], 0.25));
          MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex = 2.0 * PI
              * Localh3[MyK][MyJ][MyI] * sqrt(LocalK11[MyK][MyJ][MyI]
              * LocalK22[MyK][MyJ][MyI]) / (log(re
              / MySim->Wells[WellID].Perforations[PerfIDMine].Rw)
              + MySim->Wells[WellID].Perforations[PerfIDMine].S);
        }
      }

      i = 0;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Po;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Pw;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Pg;i++;

      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].So;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Sw;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Sg;i++;

      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Rhoo;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Rhow;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Rhog;i++;

      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Bo;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Bw;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Bg;i++;

      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Kro;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Krw;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Krg;i++;

      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Muo;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Muw;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Mug;i++;

      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].x1;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].x2;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].x3;i++;

      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].h1;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].h2;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].h3;i++;

      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Pcow;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Pcog;i++;
      InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex;

      /* Sync properties at the perforation locations */
      ierr = MPI_Bcast(InBuffer, 27, MPI_DOUBLE, MySim->Wells[WellID].Perforations[PerfIDMine].OwnerRank, PETSC_COMM_WORLD);CHKERRQ(ierr);CHKMEMQ;

      /* and now unpack the data */
      i = 0;

      MySim->Wells[WellID].Perforations[PerfIDMine].Po = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Pw = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Pg = InBuffer[i];i++;

      MySim->Wells[WellID].Perforations[PerfIDMine].So = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Sw = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Sg = InBuffer[i];i++;

      MySim->Wells[WellID].Perforations[PerfIDMine].Rhoo = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Rhow = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Rhog = InBuffer[i];i++;

      MySim->Wells[WellID].Perforations[PerfIDMine].Bo = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Bw = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Bg = InBuffer[i];i++;

      MySim->Wells[WellID].Perforations[PerfIDMine].Kro = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Krw = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Krg = InBuffer[i];i++;

      MySim->Wells[WellID].Perforations[PerfIDMine].Muo = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Muw = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Mug = InBuffer[i];i++;

      MySim->Wells[WellID].Perforations[PerfIDMine].x1 = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].x2 = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].x3 = InBuffer[i];i++;

      MySim->Wells[WellID].Perforations[PerfIDMine].h1 = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].h2 = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].h3 = InBuffer[i];i++;

      MySim->Wells[WellID].Perforations[PerfIDMine].Pcow = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].Pcog = InBuffer[i];i++;
      MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex = InBuffer[i];
       PetscPrintf(PETSC_COMM_WORLD, "\n At well: %d Value of WellIndex is:%g", WellID,MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex);
      

    }
  }

  PetscFunctionReturn(0);
}
Пример #30
0
int main(int argc,char **argv)
{
  DMMG           *dmmg_comp;          /* multilevel grid structure */
  AppCtx         user;                /* user-defined work context */
  PetscInt       mx,my,its,max_its,i;
  PetscErrorCode ierr;
  MPI_Comm       comm;
  SNES           snes;
  DA             da1,da2;
  DMComposite    pack;

  DMMG           *dmmg1,*dmmg2;
  PetscTruth     SolveSubPhysics=PETSC_FALSE,GaussSeidel=PETSC_TRUE,Jacobi=PETSC_FALSE;
  Vec            X1,X1_local,X2,X2_local;
  PetscViewer    viewer;

  PetscInitialize(&argc,&argv,(char *)0,help);
  comm = PETSC_COMM_WORLD;

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Create user context, set problem data, create vector data structures.
     Also, compute the initial guess.
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Setup Physics 1: 
        - Lap(U) - Grad_y(Omega) = 0
	- Lap(V) + Grad_x(Omega) = 0
	- Lap(Omega) + Div([U*Omega,V*Omega]) - GR*Grad_x(T) = 0
        where T is given by the given x.temp
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,3,1,0,0,&da1);CHKERRQ(ierr);
  ierr = DASetFieldName(da1,0,"x-velocity");CHKERRQ(ierr);
  ierr = DASetFieldName(da1,1,"y-velocity");CHKERRQ(ierr);
  ierr = DASetFieldName(da1,2,"Omega");CHKERRQ(ierr);

  /* Create the solver object and attach the grid/physics info */
  ierr = DMMGCreate(comm,1,&user,&dmmg1);CHKERRQ(ierr);
  ierr = DMMGSetDM(dmmg1,(DM)da1);CHKERRQ(ierr);
  ierr = DMMGSetISColoringType(dmmg1,IS_COLORING_GLOBAL);CHKERRQ(ierr);

  ierr = DMMGSetInitialGuess(dmmg1,FormInitialGuess1);CHKERRQ(ierr);
  ierr = DMMGSetSNES(dmmg1,FormFunction1,0);CHKERRQ(ierr);
  ierr = DMMGSetFromOptions(dmmg1);CHKERRQ(ierr);

  /* Set problem parameters (velocity of lid, prandtl, and grashof numbers) */  
  ierr = DAGetInfo(da1,PETSC_NULL,&mx,&my,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  user.lidvelocity = 1.0/(mx*my);
  user.prandtl     = 1.0;
  user.grashof     = 1000.0; 
  ierr = PetscOptionsGetReal(PETSC_NULL,"-lidvelocity",&user.lidvelocity,PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscOptionsGetReal(PETSC_NULL,"-prandtl",&user.prandtl,PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscOptionsGetReal(PETSC_NULL,"-grashof",&user.grashof,PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscOptionsHasName(PETSC_NULL,"-solvesubphysics",&SolveSubPhysics);CHKERRQ(ierr);
  ierr = PetscOptionsHasName(PETSC_NULL,"-Jacobi",&Jacobi);CHKERRQ(ierr);
  if (Jacobi) GaussSeidel=PETSC_FALSE;
  
  ierr = PetscPrintf(comm,"grashof: %g, ",user.grashof);CHKERRQ(ierr);
  if (GaussSeidel){
    ierr = PetscPrintf(comm,"use Block Gauss-Seidel\n");CHKERRQ(ierr);
  } else {
    ierr = PetscPrintf(comm,"use Block Jacobi\n");CHKERRQ(ierr);
  }
  ierr = PetscPrintf(comm,"===========================================\n");CHKERRQ(ierr);

  /* Solve the nonlinear system 1 */
  if (SolveSubPhysics){
    ierr = DMMGSolve(dmmg1);CHKERRQ(ierr); 
    snes = DMMGGetSNES(dmmg1);
    ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
    ierr = PetscPrintf(comm,"Physics 1: Number of Newton iterations = %D\n\n", its);CHKERRQ(ierr);
  }

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Setup Physics 2: 
        - Lap(T) + PR*Div([U*T,V*T]) = 0        
        where U and V are given by the given x.u and x.v
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,&da2);CHKERRQ(ierr);
  ierr = DASetFieldName(da2,0,"temperature");CHKERRQ(ierr);

  /* Create the solver object and attach the grid/physics info */
  ierr = DMMGCreate(comm,1,&user,&dmmg2);CHKERRQ(ierr);
  ierr = DMMGSetDM(dmmg2,(DM)da2);CHKERRQ(ierr);
  ierr = DMMGSetISColoringType(dmmg2,IS_COLORING_GLOBAL);CHKERRQ(ierr);

  ierr = DMMGSetInitialGuess(dmmg2,FormInitialGuess2);CHKERRQ(ierr);
  ierr = DMMGSetSNES(dmmg2,FormFunction2,0);CHKERRQ(ierr);
  ierr = DMMGSetFromOptions(dmmg2);CHKERRQ(ierr);

  /* Solve the nonlinear system 2 */
  if (SolveSubPhysics){
    ierr = DMMGSolve(dmmg2);CHKERRQ(ierr); 
    snes = DMMGGetSNES(dmmg2);
    ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
    ierr = PetscPrintf(comm,"Physics 2: Number of Newton iterations = %D\n\n", its);CHKERRQ(ierr);
  }

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Solve system 1 and 2 iteratively 
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DACreateLocalVector(da1,&X1_local);CHKERRQ(ierr);
  ierr = DACreateLocalVector(da2,&X2_local);CHKERRQ(ierr);

  /* Only 1 snes iteration is allowed for each subphysics */
  /*
  snes = DMMGGetSNES(dmmg1);
  ierr = SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1,PETSC_DEFAULT);CHKERRQ(ierr);
  snes = DMMGGetSNES(dmmg2);
  ierr = SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1,PETSC_DEFAULT);CHKERRQ(ierr);
  */
  max_its = 5;
  ierr = PetscOptionsGetInt(PETSC_NULL,"-mp_max_it",&max_its,PETSC_NULL);CHKERRQ(ierr);

  user.nsolve = 0;
  for (i=0; i<max_its; i++){
    ierr = PetscPrintf(comm,"\nIterative nsolve %D ...\n", user.nsolve);CHKERRQ(ierr);
    if (!GaussSeidel){
      /* get the ghosted X1_local for Physics 2 */
      X1   = DMMGGetx(dmmg1); //Jacobian
      if (i){ierr = DAVecRestoreArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr);}

      ierr = DAGlobalToLocalBegin(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr);
      ierr = DAGlobalToLocalEnd(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr);
      ierr = DAVecGetArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr);
    }

    ierr = DMMGSolve(dmmg1);CHKERRQ(ierr); 
    snes = DMMGGetSNES(dmmg1);
    ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);

    if (GaussSeidel){
      /* get the ghosted X1_local for Physics 2 */
      X1   = DMMGGetx(dmmg1); 
      if (i){ierr = DAVecRestoreArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr);}

      ierr = DAGlobalToLocalBegin(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr);
      ierr = DAGlobalToLocalEnd(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr);
      ierr = DAVecGetArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr);
    }

    ierr = PetscPrintf(comm,"  Iterative physics 1: Number of Newton iterations = %D\n", its);CHKERRQ(ierr);
    user.nsolve++;

    ierr = DMMGSolve(dmmg2);CHKERRQ(ierr); 
    snes = DMMGGetSNES(dmmg2);
    ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);

    /* get the ghosted X2_local for Physics 1 */
    X2   = DMMGGetx(dmmg2);
    if (i){ierr = DAVecRestoreArray(da2,X2_local,(Field2 **)&user.x2);CHKERRQ(ierr);}
    ierr = DAGlobalToLocalBegin(da2,X2,INSERT_VALUES,X2_local);CHKERRQ(ierr);
    ierr = DAGlobalToLocalEnd(da2,X2,INSERT_VALUES,X2_local);CHKERRQ(ierr);
    ierr = DAVecGetArray(da2,X2_local,(Field2 **)&user.x2);CHKERRQ(ierr);
    ierr = PetscPrintf(comm,"  Iterative physics 2: Number of Newton iterations = %D\n", its);CHKERRQ(ierr);  
    //user.nsolve++;
  }
  ierr = DAVecRestoreArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(da2,X2_local,(Field2 **)&user.x2);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Create the DMComposite object to manage the two grids/physics. 
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = PetscPrintf(comm,"  \n\n DMComposite iteration......\n");CHKERRQ(ierr);  
  ierr = DMCompositeCreate(comm,&pack);CHKERRQ(ierr);
  ierr = DMCompositeAddDM(pack,(DM)da1);CHKERRQ(ierr);
  ierr = DMCompositeAddDM(pack,(DM)da2);CHKERRQ(ierr);

  /* Create the solver object and attach the grid/physics info */
  ierr = DMMGCreate(comm,1,&user,&dmmg_comp);CHKERRQ(ierr);
  ierr = DMMGSetDM(dmmg_comp,(DM)pack);CHKERRQ(ierr);
  ierr = DMMGSetISColoringType(dmmg_comp,IS_COLORING_GLOBAL);CHKERRQ(ierr);

  ierr = DMMGSetInitialGuess(dmmg_comp,FormInitialGuessComp);CHKERRQ(ierr);
  ierr = DMMGSetSNES(dmmg_comp,FormFunctionComp,0);CHKERRQ(ierr);
  ierr = DMMGSetFromOptions(dmmg_comp);CHKERRQ(ierr);

  /* Solve the nonlinear system */
  /*  ierr = DMMGSolve(dmmg_comp);CHKERRQ(ierr); 
  snes = DMMGGetSNES(dmmg_comp);
  ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr);
  ierr = PetscPrintf(comm,"Composite Physics: Number of Newton iterations = %D\n\n", its);CHKERRQ(ierr);*/

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Free spaces 
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DMCompositeDestroy(pack);CHKERRQ(ierr);
  ierr = DADestroy(da1);CHKERRQ(ierr);
  ierr = DADestroy(da2);CHKERRQ(ierr);
  ierr = DMMGDestroy(dmmg_comp);CHKERRQ(ierr);

  ierr = PetscViewerASCIIOpen(comm,"log.py",&viewer);CHKERRQ(ierr);
  /* -log_summary */
  ierr = PetscLogPrintSummaryToPy(comm,viewer);CHKERRQ(ierr);
 
  /* -snes_view */  
  //snes = DMMGGetSNES(dmmg1);CHKERRQ(ierr);

  ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
    
  ierr = DMMGDestroy(dmmg1);CHKERRQ(ierr);
  ierr = DMMGDestroy(dmmg2);CHKERRQ(ierr);

  ierr = VecDestroy(X1_local);CHKERRQ(ierr);
  ierr = VecDestroy(X2_local);CHKERRQ(ierr);
  ierr = PetscFinalize();CHKERRQ(ierr);
  return 0;
}