예제 #1
0
void CopyBoundary(State *BHD, Vec gfrom, Vec gto, real zpad)
{
  PData PD;
  DA da;
  int x[3], n[3], i[3], ic[3], dim, k, N[3], border;
  PetscScalar ***gfrom_vec, ***gto_vec;

  PD = BHD->PD;
  da = BHD->da;
  FOR_DIM
    N[dim] = PD->N[dim];

  VecSet(gto, 0.0);

  border = (int) ceil( ((PD->interval[1]-PD->interval[0])-(2.*zpad))/PD->h[0]/2. );

  /* Get local portion of the grid */
  DAGetCorners(da, &(x[0]), &(x[1]), &(x[2]), &(n[0]), &(n[1]), &(n[2]));

  DAVecGetArray(da, gfrom, &gfrom_vec);
  DAVecGetArray(da, gto, &gto_vec);


/*   FOR_DIM */
/*     { */
/*       ic[0]=dim; */
/*       ic[1]=(dim+1)%3; */
/*       ic[2]=(dim+2)%3; */
/*       i[ic[0]] = 0; */
/*       if( x[ic[0]] == 0 )  */
/* 	for( i[ic[1]]=x[ic[1]]; i[ic[1]]<x[ic[1]]+n[ic[1]]; i[ic[1]]++) */
/* 	  for( i[ic[2]]=x[ic[2]]; i[ic[2]]<x[ic[2]]+n[ic[2]]; i[ic[2]]++) */
/* 	    gto_vec[i[2]][i[1]][i[0]] = gfrom_vec[i[2]][i[1]][i[0]]; */
/*       i[ic[0]] = N[ic[0]]-1; */
/*       if( x[ic[0]]+n[ic[0]] == N[ic[0]] )  */
/* 	for( i[ic[1]]=x[ic[1]]; i[ic[1]]<x[ic[1]]+n[ic[1]]; i[ic[1]]++) */
/* 	  for( i[ic[2]]=x[ic[2]]; i[ic[2]]<x[ic[2]]+n[ic[2]]; i[ic[2]]++) */
/* 	    gto_vec[i[2]][i[1]][i[0]] = gfrom_vec[i[2]][i[1]][i[0]]; */
/*     } */

  /* loop over local portion of grid */
  for(i[2]=x[2]; i[2]<x[2]+n[2]; i[2]++)
    for(i[1]=x[1]; i[1]<x[1]+n[1]; i[1]++)
      for(i[0]=x[0]; i[0]<x[0]+n[0]; i[0]++)
	{
	  if( ( i[0]<=border+1 || i[0]>=N[0]-1-border) ||
	      ( i[1]<=border+1 || i[1]>=N[1]-1-border) ||
	      ( i[2]<=border+1 || i[2]>=N[2]-1-border) )
	    gto_vec[i[2]][i[1]][i[0]] = gfrom_vec[i[2]][i[1]][i[0]];
	}


  DAVecRestoreArray(da, gfrom, &gfrom_vec);
  DAVecRestoreArray(da, gto, &gto_vec);
}
예제 #2
0
/*
   MSA_InitialPoint - Calculates the initial guess in one of three ways. 

   Input Parameters:
.  user - user-defined application context
.  X - vector for initial guess

   Output Parameters:
.  X - newly computed initial guess
*/
static int MSA_InitialPoint(AppCtx * user, Vec X)
{
  int      info;
  PetscInt   start2=-1,i,j;
  PetscReal   start1=0;
  PetscTruth flg1,flg2;

  info = PetscOptionsGetReal(PETSC_NULL,"-start",&start1,&flg1); CHKERRQ(info);
  info = PetscOptionsGetInt(PETSC_NULL,"-random",&start2,&flg2); CHKERRQ(info);

  if (flg1){ /* The zero vector is reasonable */
 
    info = VecSet(X, start1); CHKERRQ(info);

  } else if (flg2 && start2>0){ /* Try a random start between -0.5 and 0.5 */

    PetscRandom rctx;  PetscScalar np5=-0.5;

    info = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
    CHKERRQ(info);
    for (i=0; i<start2; i++){
      info = VecSetRandom(X, rctx); CHKERRQ(info);
    }
    info = PetscRandomDestroy(rctx); CHKERRQ(info);
    info = VecShift(X, np5); CHKERRQ(info);

  } else { /* Take an average of the boundary conditions */

    PetscInt xs,xm,ys,ym;
    PetscInt mx=user->mx,my=user->my;
    PetscScalar **x;
    
    /* Get local mesh boundaries */
    info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info);
    
    /* Get pointers to vector data */
    info = DAVecGetArray(user->da,X,(void**)&x);

    /* Perform local computations */    
    for (j=ys; j<ys+ym; j++){
      for (i=xs; i< xs+xm; i++){
	x[j][i] = ( ((j+1)*user->bottom[i-xs+1]+(my-j+1)*user->top[i-xs+1])/(my+2)+
		   ((i+1)*user->left[j-ys+1]+(mx-i+1)*user->right[j-ys+1])/(mx+2))/2.0; 
      }
    }
    
    /* Restore vectors */
    info = DAVecRestoreArray(user->da,X,(void**)&x);  CHKERRQ(info);

    info = PetscLogFlops(9*xm*ym); CHKERRQ(info);
    
  }
  return 0;
}
예제 #3
0
int main(int argc, char **args)
{
  PetscErrorCode  ierr;
  ierr = PetscInitialize(&argc, &args, (char *) 0, ""); CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD, "Start %s\n", __FILE__); CHKERRQ(ierr);
  MPI_Comm comm = PETSC_COMM_WORLD;

  DA da;
  Mat mat;
  int MX = 100;
  int dof = 3;

  ierr = PetscPrintf(comm,"Started Assembly\n"); CHKERRQ(ierr);
  ierr = MatMake(MX,dof,&da, &mat); CHKERRQ(ierr);
  ierr = MatWrite("J",mat); CHKERRQ(ierr);
  ierr = PetscPrintf(comm,"Finished Assembly\n"); CHKERRQ(ierr);

  Vec rhs, sol;
  ierr = DACreateGlobalVector(da,&rhs); CHKERRQ(ierr);
  ierr = DACreateGlobalVector(da,&sol); CHKERRQ(ierr);

  int i,j;
  int xs,ys,xm,ym;
  Field **array;
  ierr = DAVecGetArray(da,rhs,&array); CHKERRQ(ierr);
  ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(ierr);
  for (j = xs; j < xm; ++j) {
    for (i = ys; i < ym; ++i) {
      if( 3*MX/4 > i && i > MX/4 &&
          3*MX/4 > j && j > MX/4  )
      {
        array[j][i].u = 100.;
        array[j][i].v = 100.;
      }
    }
  }
  ierr = DAVecRestoreArray(da,rhs,&array); CHKERRQ(ierr);


  KSP ksp;
  ierr = KSPCreate(comm,&ksp); CHKERRQ(ierr);
  ierr = KSPSetType(ksp,KSPPREONLY); CHKERRQ(ierr);
  ierr = KSPSetOperators(ksp,mat,mat,DIFFERENT_NONZERO_PATTERN); CHKERRQ(ierr);
  ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);

  //Split pressure from velocity
  PC pc;
  ierr = KSPGetPC(ksp,&pc); CHKERRQ(ierr);
  ierr = PCSetType(pc, PCFIELDSPLIT); CHKERRQ(ierr);
  ierr = PCFieldSplitSetType(pc,PC_COMPOSITE_SCHUR); CHKERRQ(ierr);
  ierr = PCFieldSplitSetBlockSize(pc,3); CHKERRQ(ierr);
  ierr = PCFieldSplitSetFields(pc,2,(int[]){0,1}); CHKERRQ(ierr);
예제 #4
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;}
예제 #5
0
PetscErrorCode  FormFunction1(SNES snes,Vec X,Vec F,void *ptr)
{
  AppCtx         *user = (AppCtx*)ptr;
  PetscErrorCode ierr;
  PetscInt       i,j,k,loc,mx,my,mz,xs,ys,zs,xm,ym,zm,Xs,Ys,Zs,Xm,Ym,Zm,base1,base2;
  PetscReal      two = 2.0,one = 1.0,lambda,Hx,Hy,Hz,HxHzdHy,HyHzdHx,HxHydHz;
  PetscScalar    u,uxx,uyy,sc,*x,*f,uzz;
  Vec            localX = user->localX,localF = user->localF; 

  mx      = user->mx; my = user->my; mz = user->mz; lambda = user->param;
  Hx      = one / (PetscReal)(mx-1);
  Hy      = one / (PetscReal)(my-1);
  Hz      = one / (PetscReal)(mz-1);
  sc      = Hx*Hy*Hz*lambda; HxHzdHy  = Hx*Hz/Hy; HyHzdHx  = Hy*Hz/Hx;
  HxHydHz = Hx*Hy/Hz;

  ierr = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX);
  ierr = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX);
  ierr = VecGetArray(localX,&x);CHKERRQ(ierr);
  ierr = VecGetArray(localF,&f);CHKERRQ(ierr);

  ierr = DAGetCorners(user->da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
  ierr = DAGetGhostCorners(user->da,&Xs,&Ys,&Zs,&Xm,&Ym,&Zm);CHKERRQ(ierr);

  for (k=zs; k<zs+zm; k++) {
    base1 = (Xm*Ym)*(k-Zs); 
    for (j=ys; j<ys+ym; j++) {
      base2 = base1 + (j-Ys)*Xm; 
      for (i=xs; i<xs+xm; i++) {
        loc = base2 + (i-Xs);
        if (i == 0 || j == 0 || k== 0 || i == mx-1 || j == my-1 || k == mz-1) {
          f[loc] = x[loc]; 
        }
        else {
          u = x[loc];
          uxx = (two*u - x[loc-1] - x[loc+1])*HyHzdHx;
          uyy = (two*u - x[loc-Xm] - x[loc+Xm])*HxHzdHy;
          uzz = (two*u - x[loc-Xm*Ym] - x[loc+Xm*Ym])*HxHydHz;
          f[loc] = uxx + uyy + uzz - sc*PetscExpScalar(u);
        }
      }  
    }
  }  
  ierr = VecRestoreArray(localX,&x);CHKERRQ(ierr);
  ierr = VecRestoreArray(localF,&f);CHKERRQ(ierr);
  /* stick values into global vector */
  ierr = DALocalToGlobal(user->da,localF,INSERT_VALUES,F);CHKERRQ(ierr);
  ierr = PetscLogFlops(11.0*ym*xm*zm);CHKERRQ(ierr);
  return 0; 
}
예제 #6
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;
}
예제 #7
0
/*
   PostCheck - Optional user-defined routine that checks the validity of
   candidate steps of a line search method.  Set by SNESLineSearchSetPostCheck().

   Input Parameters:
   snes - the SNES context
   ctx  - optional user-defined context for private data for the 
          monitor routine, as set by SNESLineSearchSetPostCheck()
   xcurrent - current solution
   y - search direction and length
   x    - the new candidate iterate

   Output Parameters:
   y    - proposed step (search direction and length) (possibly changed)
   x    - current iterate (possibly modified)
   
 */
PetscErrorCode PostCheck(SNES snes,Vec xcurrent,Vec y,Vec x,void *ctx,PetscTruth *changed_y,PetscTruth *changed_x)
{
  PetscErrorCode ierr;
  PetscInt       i,iter,xs,xm;
  StepCheckCtx   *check = (StepCheckCtx*) ctx;
  ApplicationCtx *user = check->user;
  PetscScalar    *xa,*xa_last,tmp;
  PetscReal      rdiff;
  DA             da;

  PetscFunctionBegin;
  *changed_x = PETSC_FALSE;
  *changed_y = PETSC_FALSE;
  ierr = SNESGetIterationNumber(snes,&iter);CHKERRQ(ierr);

  /* iteration 1 indicates we are working on the second iteration */
  if (iter > 0) {
    da   = user->da;
    ierr = PetscPrintf(PETSC_COMM_WORLD,"Checking candidate step at iteration %D with tolerance %G\n",iter,check->tolerance);CHKERRQ(ierr);

    /* Access local array data */
    ierr = DAVecGetArray(da,check->last_step,&xa_last);CHKERRQ(ierr);
    ierr = DAVecGetArray(da,x,&xa);CHKERRQ(ierr);
    ierr = DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);

    /* 
       If we fail the user-defined check for validity of the candidate iterate,
       then modify the iterate as we like.  (Note that the particular modification 
       below is intended simply to demonstrate how to manipulate this data, not
       as a meaningful or appropriate choice.)
    */
    for (i=xs; i<xs+xm; i++) {
      if (!PetscAbsScalar(xa[i])) rdiff = 2*check->tolerance; else rdiff = PetscAbsScalar((xa[i] - xa_last[i])/xa[i]);
      if (rdiff > check->tolerance) {
        tmp        = xa[i];
        xa[i]      = .5*(xa[i] + xa_last[i]);
        *changed_x = PETSC_TRUE;
        ierr       = PetscPrintf(PETSC_COMM_WORLD,"  Altering entry %D: x=%G, x_last=%G, diff=%G, x_new=%G\n",
                                i,PetscAbsScalar(tmp),PetscAbsScalar(xa_last[i]),rdiff,PetscAbsScalar(xa[i]));CHKERRQ(ierr);
      }
    }
    ierr = DAVecRestoreArray(da,check->last_step,&xa_last);CHKERRQ(ierr);
    ierr = DAVecRestoreArray(da,x,&xa);CHKERRQ(ierr);
  }
  ierr = VecCopy(x,check->last_step);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
예제 #8
0
int Initialize(DMMG *dmmg)
/* ------------------------------------------------------------------- */
{
    AppCtx    *user  = (AppCtx*)dmmg[0]->user;
    Parameter *param;
    DA        da;
    PetscReal PI = 3.14159265358979323846;
    PetscReal sigma,xc,zc;
    PetscReal dx=user->grid->dx,dz=user->grid->dz;
    int       i,j,ierr,is,js,im,jm;
    Field     **x;
    ierr = PetscBagGetData(user->bag,(void**)&param);
    CHKERRQ(ierr);
    sigma=param->sigma;
    xc=param->xctr;
    zc=param->zctr;

    /* Get the DA and grid */
    da = (DA)(dmmg[0]->dm);
    ierr = DAGetCorners(da,&is,&js,PETSC_NULL,&im,&jm,PETSC_NULL);
    CHKERRQ(ierr);
    ierr = DAVecGetArray(da,user->Xold,(void**)&x);
    CHKERRQ(ierr);

    for (j=js; j<js+jm; j++) {
        for (i=is; i<is+im; i++) {
            if (param->flow_type == SHEAR_CELL) {
                x[j][i].u = -sin(PI*i*dx)*cos(PI*j*dz)/dx;
                x[j][i].w =  sin(PI*j*dz)*cos(PI*i*dx)/dz;
            } else {
                x[j][i].u =  0.0;
                x[j][i].w = -1.0/dz;
            }
            x[j][i].phi = 100*exp(-0.5*((i*dx-xc)*(i*dx-xc)+(j*dz-zc)*(j*dz-zc))/sigma/sigma);
        }
    }

    /* restore the grid to it's vector */
    ierr = DAVecRestoreArray(da,user->Xold,(void**)&x);
    CHKERRQ(ierr);
    ierr = VecCopy(user->Xold, DMMGGetx(dmmg));
    CHKERRQ(ierr);
    return 0;
}
예제 #9
0
int FormJacobian_Grid(GridCtx *grid,Mat *J)
{
  Mat            jac = *J;
  PetscErrorCode ierr;
  PetscInt       i,j,row,mx,my,xs,ys,xm,ym,Xs,Ys,Xm,Ym,col[5];
  PetscInt       nloc,*ltog,grow;
  PetscScalar    two = 2.0,one = 1.0,v[5],hx,hy,hxdhy,hydhx,value;

  mx = grid->mx;            my = grid->my;            
  hx = one/(PetscReal)(mx-1);  hy = one/(PetscReal)(my-1);
  hxdhy = hx/hy;            hydhx = hy/hx;

  /* Get ghost points */
  ierr = DAGetCorners(grid->da,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr);
  ierr = DAGetGhostCorners(grid->da,&Xs,&Ys,0,&Xm,&Ym,0);CHKERRQ(ierr);
  ierr = DAGetGlobalIndices(grid->da,&nloc,&ltog);CHKERRQ(ierr);

  /* Evaluate Jacobian of function */
  for (j=ys; j<ys+ym; j++) {
    row = (j - Ys)*Xm + xs - Xs - 1; 
    for (i=xs; i<xs+xm; i++) {
      row++;
      grow = ltog[row];
      if (i > 0 && i < mx-1 && j > 0 && j < my-1) {
        v[0] = -hxdhy; col[0] = ltog[row - Xm];
        v[1] = -hydhx; col[1] = ltog[row - 1];
        v[2] = two*(hydhx + hxdhy); col[2] = grow;
        v[3] = -hydhx; col[3] = ltog[row + 1];
        v[4] = -hxdhy; col[4] = ltog[row + Xm];
        ierr = MatSetValues(jac,1,&grow,5,col,v,INSERT_VALUES);CHKERRQ(ierr);
      } else if ((i > 0 && i < mx-1) || (j > 0 && j < my-1)){
        value = .5*two*(hydhx + hxdhy);
        ierr = MatSetValues(jac,1,&grow,1,&grow,&value,INSERT_VALUES);CHKERRQ(ierr);
      } else {
        value = .25*two*(hydhx + hxdhy);
        ierr = MatSetValues(jac,1,&grow,1,&grow,&value,INSERT_VALUES);CHKERRQ(ierr);
      }
    }
  }
  ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  return 0;
}
예제 #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
/* 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;
}
예제 #12
0
int ComputeB(AppCtx* user)
{
  int info;
  PetscInt i,j,k;
  PetscInt nx,ny,xs,xm,gxs,gxm,ys,ym,gys,gym;
  PetscReal two=2.0, pi=4.0*atan(1.0);
  PetscReal hx,hy,ehxhy;
  PetscReal temp,*b;
  PetscReal ecc=user->ecc;

  nx=user->nx;
  ny=user->ny;
  hx=two*pi/(nx+1.0);
  hy=two*user->b/(ny+1.0);
  ehxhy = ecc*hx*hy;


  /*
     Get local grid boundaries
  */
  info = DAGetCorners(user->da,&xs,&ys,TAO_NULL,&xm,&ym,TAO_NULL); CHKERRQ(info);
  info = DAGetGhostCorners(user->da,&gxs,&gys,TAO_NULL,&gxm,&gym,TAO_NULL); CHKERRQ(info);
  

  /* Compute the linear term in the objective function */  
  info = VecGetArray(user->B,&b); CHKERRQ(info);
  for (i=xs; i<xs+xm; i++){
    temp=sin((i+1)*hx);
    for (j=ys; j<ys+ym; j++){
      k=xm*(j-ys)+(i-xs);
      b[k]=  - ehxhy*temp;
    }
  }
  info = VecRestoreArray(user->B,&b); CHKERRQ(info);
  info = PetscLogFlops(5*xm*ym+3*xm); CHKERRQ(info);

  return 0;
}
예제 #13
0
PetscErrorCode  FormInitialGuess1(AppCtx *user,Vec X)
{
  PetscInt       i,j,k,loc,mx,my,mz,xs,ys,zs,xm,ym,zm,Xm,Ym,Zm,Xs,Ys,Zs,base1;
  PetscErrorCode ierr;
  PetscReal      one = 1.0,lambda,temp1,temp,Hx,Hy;
  PetscScalar    *x;
  Vec            localX = user->localX;

  mx	 = user->mx; my	 = user->my; mz = user->mz; lambda = user->param;
  Hx     = one / (PetscReal)(mx-1);     Hy     = one / (PetscReal)(my-1);

  ierr  = VecGetArray(localX,&x);CHKERRQ(ierr);
  temp1 = lambda/(lambda + one);
  ierr  = DAGetCorners(user->da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
  ierr  = DAGetGhostCorners(user->da,&Xs,&Ys,&Zs,&Xm,&Ym,&Zm);CHKERRQ(ierr);
 
  for (k=zs; k<zs+zm; k++) {
    base1 = (Xm*Ym)*(k-Zs);
    for (j=ys; j<ys+ym; j++) {
      temp = (PetscReal)(PetscMin(j,my-j-1))*Hy;
      for (i=xs; i<xs+xm; i++) {
        loc = base1 + i-Xs + (j-Ys)*Xm; 
        if (i == 0 || j == 0 || k == 0 || i==mx-1 || j==my-1 || k==mz-1) {
          x[loc] = 0.0; 
          continue;
        }
        x[loc] = temp1*sqrt(PetscMin((PetscReal)(PetscMin(i,mx-i-1))*Hx,temp)); 
      }
    }
  }

  ierr = VecRestoreArray(localX,&x);CHKERRQ(ierr);
  /* stick values into global vector */
  ierr = DALocalToGlobal(user->da,localX,INSERT_VALUES,X);CHKERRQ(ierr);
  return 0;
}/* --------------------  Evaluate Function F(x) --------------------- */
예제 #14
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;
}
예제 #15
0
int FormBratuFunction(SNES snes, Vec v, Vec f, void* ctx)
{
	UserBratuCtx* bratu = (UserBratuCtx *) ctx;
	DA da = bratu->da;
	double lambda = bratu->lambda;
	double h = bratu->h;
	Vec lv;
	int i,j;
	int lli, llj, ni, nj;
	const double **varr;
	double **fvarr;

	DAGetCorners(da, &lli, &llj, 0, &ni, &nj, 0);
	DAGetLocalVector(da, &lv);
	DAGlobalToLocalBegin(da, v, INSERT_VALUES, lv);
	DAGlobalToLocalEnd(da, v, INSERT_VALUES,lv);

	DAVecGetArray(da, lv, (void**) &varr);
	DAVecGetArray(da, f, (void**) &fvarr);

	for(j=llj; j<llj+nj; j++){
		for(i=lli; i<lli+ni; i++){
			if(i==0 || j==0 ||i=bratu->n+1 || j==bratu->n+1){
				fvarr[j][i] = 0.0;
			}
			else{
				fvarr[j][i] = -(varr[j-1][i] + varr[j][i-1] + varr[j+1][i] + varr[j][i+1] - 4*varr[j][i])/(h*h) - lambda*exp(varr[j][i]);
			}
		}
	}
	DAVecRestoreArray(da, f, (void**) &fvarr);
	DAVecRestoreArray(da, lv, (void**) &varr);
	DARestoreLocalVector(da, &lv);

	return 0;
}
예제 #16
0
파일: Production.c 프로젝트: yye00/Defiant
/* 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);
}
예제 #17
0
파일: Production.c 프로젝트: yye00/Defiant
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);
}
예제 #18
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);
}
예제 #19
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
}
예제 #20
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();
}
예제 #21
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);
}
예제 #22
0
/* 
   MSA_BoundaryConditions -  Calculates the boundary conditions for
   the region.

   Input Parameter:
.  user - user-defined application context

   Output Parameter:
.  user - user-defined application context
*/
static int MSA_BoundaryConditions(AppCtx * user)
{
  int        info;
  PetscInt     i,j,k,limit=0,maxits=5;
  PetscInt     xs,ys,xm,ym,gxs,gys,gxm,gym;
  PetscInt     mx=user->mx,my=user->my;
  PetscInt     bsize=0, lsize=0, tsize=0, rsize=0;
  double     one=1.0, two=2.0, three=3.0, tol=1e-10;
  double     fnorm,det,hx,hy,xt=0,yt=0;
  double     u1,u2,nf1,nf2,njac11,njac12,njac21,njac22;
  double     b=-0.5, t=0.5, l=-0.5, r=0.5;
  double     *boundary;
  PetscTruth   flg;

  /* Get local mesh boundaries */
  info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info);
  info = DAGetGhostCorners(user->da,&gxs,&gys,PETSC_NULL,&gxm,&gym,PETSC_NULL); CHKERRQ(info);

  bsize=xm+2;
  lsize=ym+2;
  rsize=ym+2;
  tsize=xm+2;

  info = PetscMalloc(bsize*sizeof(double),&user->bottom); CHKERRQ(info);
  info = PetscMalloc(tsize*sizeof(double),&user->top); CHKERRQ(info);
  info = PetscMalloc(lsize*sizeof(double),&user->left); CHKERRQ(info);
  info = PetscMalloc(rsize*sizeof(double),&user->right); CHKERRQ(info);

  hx= (r-l)/(mx+1); hy=(t-b)/(my+1);

  for (j=0; j<4; j++){
    if (j==0){
      yt=b;
      xt=l+hx*xs;
      limit=bsize;
      boundary=user->bottom;
    } else if (j==1){
      yt=t;
      xt=l+hx*xs;
      limit=tsize;
      boundary=user->top;
    } else if (j==2){
      yt=b+hy*ys;
      xt=l;
      limit=lsize;
      boundary=user->left;
    } else { //if (j==3)
      yt=b+hy*ys;
      xt=r;
      limit=rsize;
      boundary=user->right;
    }

    for (i=0; i<limit; i++){
      u1=xt;
      u2=-yt;
      for (k=0; k<maxits; k++){
	nf1=u1 + u1*u2*u2 - u1*u1*u1/three-xt;
	nf2=-u2 - u1*u1*u2 + u2*u2*u2/three-yt;
	fnorm=sqrt(nf1*nf1+nf2*nf2);
	if (fnorm <= tol) break;
	njac11=one+u2*u2-u1*u1;
	njac12=two*u1*u2;
	njac21=-two*u1*u2;
	njac22=-one - u1*u1 + u2*u2;
	det = njac11*njac22-njac21*njac12;
	u1 = u1-(njac22*nf1-njac12*nf2)/det;
	u2 = u2-(njac11*nf2-njac21*nf1)/det;
      }

      boundary[i]=u1*u1-u2*u2;
      if (j==0 || j==1) {
	xt=xt+hx;
      } else { // if (j==2 || j==3)
	yt=yt+hy;
      }
      
    }

  }

  /* Scale the boundary if desired */
  if (1==1){ 
    PetscReal scl = 1.0;

    info = PetscOptionsGetReal(PETSC_NULL,"-bottom",&scl,&flg); 
    CHKERRQ(info);
    if (flg){
      for (i=0;i<bsize;i++) user->bottom[i]*=scl;
    }

    info = PetscOptionsGetReal(PETSC_NULL,"-top",&scl,&flg); 
    CHKERRQ(info);
    if (flg){
      for (i=0;i<tsize;i++) user->top[i]*=scl;
    }

    info = PetscOptionsGetReal(PETSC_NULL,"-right",&scl,&flg); 
    CHKERRQ(info);
    if (flg){
      for (i=0;i<rsize;i++) user->right[i]*=scl;
    }

    info = PetscOptionsGetReal(PETSC_NULL,"-left",&scl,&flg); 
    CHKERRQ(info);
    if (flg){
      for (i=0;i<lsize;i++) user->left[i]*=scl;
    }
  }
  
  return 0;
}
예제 #23
0
/*
   QuadraticH - Evaluates Hessian matrix.

   Input Parameters:
.  user - user-defined context, as set by TaoSetHessian()
.  X    - input vector

   Output Parameter:
.  H    - Hessian matrix
*/
int QuadraticH(AppCtx *user, Vec X, Mat Hessian)
{
  int    info;
  PetscInt i,j,k;
  PetscInt mx=user->mx, my=user->my;
  PetscInt xs,xm,gxs,gxm,ys,ym,gys,gym;
  double hx=1.0/(mx+1), hy=1.0/(my+1), hydhx=hy/hx, hxdhy=hx/hy;
  double f1,f2,f3,f4,f5,f6,d1,d2,d3,d4,d5,d6,d7,d8,xc,xl,xr,xt,xb,xlt,xrb;
  double hl,hr,ht,hb,hc,htl,hbr;
  PetscScalar **x, v[7];
  MatStencil col[7],row;
  Vec    localX;
  PetscTruth assembled;

  /* Get local mesh boundaries */
  info = DAGetLocalVector(user->da,&localX);CHKERRQ(info);

  info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info);
  info = DAGetGhostCorners(user->da,&gxs,&gys,PETSC_NULL,&gxm,&gym,PETSC_NULL); CHKERRQ(info);

  /* Scatter ghost points to local vector */
  info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info);
  info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info);

  /* Get pointers to vector data */
  info = DAVecGetArray(user->da,localX,(void**)&x);

  /* Initialize matrix entries to zero */
  info = MatAssembled(Hessian,&assembled); CHKERRQ(info);
  if (assembled){info = MatZeroEntries(Hessian);  CHKERRQ(info);}


  /* Set various matrix options */
  info = MatSetOption(Hessian,MAT_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE); CHKERRQ(info);

  /* Compute Hessian over the locally owned part of the mesh */

  for (j=ys; j<ys+ym; j++){
      
    for (i=xs; i< xs+xm; i++){

      xc = x[j][i];
      xlt=xrb=xl=xr=xb=xt=xc;

      /* Left side */
      if (i==0){
        xl  = user->left[j-ys+1];
        xlt = user->left[j-ys+2];
      } else {
        xl  = x[j][i-1];
      }
      
      if (j==0){
        xb  = user->bottom[i-xs+1];
        xrb = user->bottom[i-xs+2];
      } else {
        xb  = x[j-1][i];
      }
      
      if (i+1 == mx){
        xr  = user->right[j-ys+1];
        xrb = user->right[j-ys];
      } else {
        xr  = x[j][i+1];
      }

      if (j+1==my){
        xt  = user->top[i-xs+1];
        xlt = user->top[i-xs];
      }else {
        xt  = x[j+1][i];
      }

      if (i>0 && j+1<my){
        xlt = x[j+1][i-1];
      }
      if (j>0 && i+1<mx){
        xrb = x[j-1][i+1];
      }


      d1 = (xc-xl)/hx;
      d2 = (xc-xr)/hx;
      d3 = (xc-xt)/hy;
      d4 = (xc-xb)/hy;
      d5 = (xrb-xr)/hy;
      d6 = (xrb-xb)/hx;
      d7 = (xlt-xl)/hy;
      d8 = (xlt-xt)/hx;
      
      f1 = sqrt( 1.0 + d1*d1 + d7*d7);
      f2 = sqrt( 1.0 + d1*d1 + d4*d4);
      f3 = sqrt( 1.0 + d3*d3 + d8*d8);
      f4 = sqrt( 1.0 + d3*d3 + d2*d2);
      f5 = sqrt( 1.0 + d2*d2 + d5*d5);
      f6 = sqrt( 1.0 + d4*d4 + d6*d6);


      hl = (-hydhx*(1.0+d7*d7)+d1*d7)/(f1*f1*f1)+
	(-hydhx*(1.0+d4*d4)+d1*d4)/(f2*f2*f2);
      hr = (-hydhx*(1.0+d5*d5)+d2*d5)/(f5*f5*f5)+
	(-hydhx*(1.0+d3*d3)+d2*d3)/(f4*f4*f4);
      ht = (-hxdhy*(1.0+d8*d8)+d3*d8)/(f3*f3*f3)+
	(-hxdhy*(1.0+d2*d2)+d2*d3)/(f4*f4*f4);
      hb = (-hxdhy*(1.0+d6*d6)+d4*d6)/(f6*f6*f6)+
	(-hxdhy*(1.0+d1*d1)+d1*d4)/(f2*f2*f2);

      hbr = -d2*d5/(f5*f5*f5) - d4*d6/(f6*f6*f6);
      htl = -d1*d7/(f1*f1*f1) - d3*d8/(f3*f3*f3);

      hc = hydhx*(1.0+d7*d7)/(f1*f1*f1) + hxdhy*(1.0+d8*d8)/(f3*f3*f3) +
	hydhx*(1.0+d5*d5)/(f5*f5*f5) + hxdhy*(1.0+d6*d6)/(f6*f6*f6) +
	(hxdhy*(1.0+d1*d1)+hydhx*(1.0+d4*d4)-2*d1*d4)/(f2*f2*f2) +
	(hxdhy*(1.0+d2*d2)+hydhx*(1.0+d3*d3)-2*d2*d3)/(f4*f4*f4);

      hl/=2.0; hr/=2.0; ht/=2.0; hb/=2.0; hbr/=2.0; htl/=2.0;  hc/=2.0; 

      row.j = j; row.i = i;
      k=0;
      if (j>0){ 
	v[k]=hb;
	col[k].j = j - 1; col[k].i = i;
	k++;
      }
      
      if (j>0 && i < mx -1){
	v[k]=hbr;
	col[k].j = j - 1; col[k].i = i+1;
	k++;
      }
      
      if (i>0){
	v[k]= hl;
	col[k].j = j; col[k].i = i-1;
	k++;
      }
      
      v[k]= hc;
      col[k].j = j; col[k].i = i;
      k++;
      
      if (i < mx-1 ){
	v[k]= hr; 
	col[k].j = j; col[k].i = i+1;
	k++;
      }
      
      if (i>0 && j < my-1 ){
	v[k]= htl;
	col[k].j = j+1; col[k].i = i-1;
	k++;
      }
      
      if (j < my-1 ){
	v[k]= ht; 
	col[k].j = j+1; col[k].i = i;
	k++;
      }
      
      /* 
	 Set matrix values using local numbering, which was defined
	 earlier, in the main routine.
      */
      info = MatSetValuesStencil(Hessian,1,&row,k,col,v,INSERT_VALUES);
      CHKERRQ(info);
      
    }
  }
  
  /* Restore vectors */
  info = DAVecRestoreArray(user->da,localX,(void**)&x);

  info = DARestoreLocalVector(user->da,&localX); CHKERRQ(info);

  /* Assemble the matrix */
  info = MatAssemblyBegin(Hessian,MAT_FINAL_ASSEMBLY); CHKERRQ(info);
  info = MatAssemblyEnd(Hessian,MAT_FINAL_ASSEMBLY); CHKERRQ(info);

  info = PetscLogFlops(199*xm*ym); CHKERRQ(info);
  return 0;
}
예제 #24
0
/*  FormFunctionGradient - Evaluates the function and corresponding gradient.

    Input Parameters:
.   taoapp     - the TAO_APPLICATION context
.   XX      - input vector
.   userCtx - optional user-defined context, as set by TaoSetFunctionGradient()
    
    Output Parameters:
.   fcn     - the newly evaluated function
.   GG       - vector containing the newly evaluated gradient
*/
int FormFunctionGradient(TAO_APPLICATION taoapp, Vec X, double *fcn,Vec G,void *userCtx){

  AppCtx * user = (AppCtx *) userCtx;
  int    info;
  PetscInt i,j;
  PetscInt mx=user->mx, my=user->my;
  PetscInt xs,xm,gxs,gxm,ys,ym,gys,gym;
  double ft=0;
  double hx=1.0/(mx+1),hy=1.0/(my+1), hydhx=hy/hx, hxdhy=hx/hy, area=0.5*hx*hy;
  double rhx=mx+1, rhy=my+1;
  double f1,f2,f3,f4,f5,f6,d1,d2,d3,d4,d5,d6,d7,d8,xc,xl,xr,xt,xb,xlt,xrb;
  double df1dxc,df2dxc,df3dxc,df4dxc,df5dxc,df6dxc;
  PetscScalar **g, **x;
  Vec    localX;

  /* Get local mesh boundaries */
  info = DAGetLocalVector(user->da,&localX);CHKERRQ(info);

  info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info);
  info = DAGetGhostCorners(user->da,&gxs,&gys,PETSC_NULL,&gxm,&gym,PETSC_NULL); CHKERRQ(info);

  /* Scatter ghost points to local vector */
  info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info);
  info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info);

  /* Get pointers to vector data */
  info = DAVecGetArray(user->da,localX,(void**)&x);
  info = DAVecGetArray(user->da,G,(void**)&g);

  /* Compute function and gradient over the locally owned part of the mesh */
  for (j=ys; j<ys+ym; j++){
    for (i=xs; i< xs+xm; i++){
      
      xc = x[j][i];
      xlt=xrb=xl=xr=xb=xt=xc;
      
      if (i==0){ /* left side */
        xl= user->left[j-ys+1];
        xlt = user->left[j-ys+2];
      } else {
        xl = x[j][i-1];
      }

      if (j==0){ /* bottom side */
        xb=user->bottom[i-xs+1];
        xrb =user->bottom[i-xs+2];
      } else {
        xb = x[j-1][i];
      }
      
      if (i+1 == gxs+gxm){ /* right side */
        xr=user->right[j-ys+1];
        xrb = user->right[j-ys];
      } else {
        xr = x[j][i+1];
      }

      if (j+1==gys+gym){ /* top side */
        xt=user->top[i-xs+1];
        xlt = user->top[i-xs];
      }else {
        xt = x[j+1][i];
      }

      if (i>gxs && j+1<gys+gym){
        xlt = x[j+1][i-1];
      }
      if (j>gys && i+1<gxs+gxm){
        xrb = x[j-1][i+1];
      }

      d1 = (xc-xl);
      d2 = (xc-xr);
      d3 = (xc-xt);
      d4 = (xc-xb);
      d5 = (xr-xrb);
      d6 = (xrb-xb);
      d7 = (xlt-xl);
      d8 = (xt-xlt);
      
      df1dxc = d1*hydhx;
      df2dxc = ( d1*hydhx + d4*hxdhy );
      df3dxc = d3*hxdhy;
      df4dxc = ( d2*hydhx + d3*hxdhy );
      df5dxc = d2*hydhx;
      df6dxc = d4*hxdhy;

      d1 *= rhx;
      d2 *= rhx;
      d3 *= rhy;
      d4 *= rhy;
      d5 *= rhy;
      d6 *= rhx;
      d7 *= rhy;
      d8 *= rhx;

      f1 = sqrt( 1.0 + d1*d1 + d7*d7);
      f2 = sqrt( 1.0 + d1*d1 + d4*d4);
      f3 = sqrt( 1.0 + d3*d3 + d8*d8);
      f4 = sqrt( 1.0 + d3*d3 + d2*d2);
      f5 = sqrt( 1.0 + d2*d2 + d5*d5);
      f6 = sqrt( 1.0 + d4*d4 + d6*d6);
      
      f2 = sqrt( 1.0 + d1*d1 + d4*d4);
      f4 = sqrt( 1.0 + d3*d3 + d2*d2);

      ft = ft + (f2 + f4);

      df1dxc /= f1;
      df2dxc /= f2;
      df3dxc /= f3;
      df4dxc /= f4;
      df5dxc /= f5;
      df6dxc /= f6;

      g[j][i] = (df1dxc+df2dxc+df3dxc+df4dxc+df5dxc+df6dxc ) * 0.5;
      
    }
  }

  /* Compute triangular areas along the border of the domain. */
  if (xs==0){ /* left side */
    for (j=ys; j<ys+ym; j++){
      d3=(user->left[j-ys+1] - user->left[j-ys+2])*rhy;
      d2=(user->left[j-ys+1] - x[j][0]) *rhx;
      ft = ft+sqrt( 1.0 + d3*d3 + d2*d2);
    }
  }
  if (ys==0){ /* bottom side */
    for (i=xs; i<xs+xm; i++){
      d2=(user->bottom[i+1-xs]-user->bottom[i-xs+2])*rhx;
      d3=(user->bottom[i-xs+1]-x[0][i])*rhy;
      ft = ft+sqrt( 1.0 + d3*d3 + d2*d2);
    }
  }

  if (xs+xm==mx){ /* right side */
    for (j=ys; j< ys+ym; j++){
      d1=(x[j][mx-1] - user->right[j-ys+1])*rhx;
      d4=(user->right[j-ys]-user->right[j-ys+1])*rhy;
      ft = ft+sqrt( 1.0 + d1*d1 + d4*d4);
    }
  }
  if (ys+ym==my){ /* top side */
    for (i=xs; i<xs+xm; i++){
      d1=(x[my-1][i] - user->top[i-xs+1])*rhy;
      d4=(user->top[i-xs+1] - user->top[i-xs])*rhx;
      ft = ft+sqrt( 1.0 + d1*d1 + d4*d4);
    }
  }

  if (ys==0 && xs==0){
    d1=(user->left[0]-user->left[1])/hy;
    d2=(user->bottom[0]-user->bottom[1])*rhx;
    ft +=sqrt( 1.0 + d1*d1 + d2*d2);
  }
  if (ys+ym == my && xs+xm == mx){
    d1=(user->right[ym+1] - user->right[ym])*rhy;
    d2=(user->top[xm+1] - user->top[xm])*rhx;
    ft +=sqrt( 1.0 + d1*d1 + d2*d2);
  }

  ft=ft*area;
  info = MPI_Allreduce(&ft,fcn,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);CHKERRQ(info);

  /* Restore vectors */
  info = DAVecRestoreArray(user->da,localX,(void**)&x);
  info = DAVecRestoreArray(user->da,G,(void**)&g);

  /* Scatter values to global vector */
  info = DARestoreLocalVector(user->da,&localX); CHKERRQ(info);

  info = PetscLogFlops(67*xm*ym); CHKERRQ(info);

  return 0;
}
예제 #25
0
/* 
   FormHessian computes the quadratic term in the quadratic objective function 
   Notice that the objective function in this problem is quadratic (therefore a constant
   hessian).  If using a nonquadratic solver, then you might want to reconsider this function
*/
int FormHessian(TAO_APPLICATION taoapp,Vec X,Mat *H, Mat *Hpre, MatStructure *flg, void *ptr)
{
  AppCtx* user=(AppCtx*)ptr;
  int info;
  PetscInt i,j,k;
  PetscInt col[5],row,nx,ny,xs,xm,gxs,gxm,ys,ym,gys,gym;
  PetscReal one=1.0, two=2.0, six=6.0,pi=4.0*atan(1.0);
  PetscReal hx,hy,hxhy,hxhx,hyhy;
  PetscReal xi,v[5];
  PetscReal ecc=user->ecc, trule1,trule2,trule3,trule4,trule5,trule6;
  PetscReal vmiddle, vup, vdown, vleft, vright;
  Mat hes=*H;
  PetscTruth assembled;

  nx=user->nx;
  ny=user->ny;
  hx=two*pi/(nx+1.0);
  hy=two*user->b/(ny+1.0);
  hxhy=hx*hy;
  hxhx=one/(hx*hx);
  hyhy=one/(hy*hy);

  *flg=SAME_NONZERO_PATTERN;
  /*
    Get local grid boundaries
  */
  info = DAGetCorners(user->da,&xs,&ys,TAO_NULL,&xm,&ym,TAO_NULL); CHKERRQ(info);
  info = DAGetGhostCorners(user->da,&gxs,&gys,TAO_NULL,&gxm,&gym,TAO_NULL); CHKERRQ(info);
  
  info = MatAssembled(hes,&assembled); CHKERRQ(info);
  if (assembled){info = MatZeroEntries(hes);  CHKERRQ(info);}

  for (i=xs; i< xs+xm; i++){
    xi=(i+1)*hx;
    trule1=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi,ecc) ) / six; /* L(i,j) */
    trule2=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi,ecc) ) / six; /* U(i,j) */
    trule3=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi+hx,ecc) ) / six; /* U(i+1,j) */
    trule4=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi-hx,ecc) ) / six; /* L(i-1,j) */
    trule5=trule1; /* L(i,j-1) */
    trule6=trule2; /* U(i,j+1) */

    vdown=-(trule5+trule2)*hyhy;
    vleft=-hxhx*(trule2+trule4);
    vright= -hxhx*(trule1+trule3);
    vup=-hyhy*(trule1+trule6);
    vmiddle=(hxhx)*(trule1+trule2+trule3+trule4)+hyhy*(trule1+trule2+trule5+trule6);
    v[0]=0; v[1]=0; v[2]=0; v[3]=0; v[4]=0;

    for (j=ys; j<ys+ym; j++){
      row=(j-gys)*gxm + (i-gxs);
       
      k=0;
      if (j>gys){ 
	v[k]=vdown; col[k]=row - gxm; k++;
      }
       
      if (i>gxs){
	v[k]= vleft; col[k]=row - 1; k++;
      }

      v[k]= vmiddle; col[k]=row; k++;
       
      if (i+1 < gxs+gxm){
	v[k]= vright; col[k]=row+1; k++;
      }
       
      if (j+1 <gys+gym){
	v[k]= vup; col[k] = row+gxm; k++;
      }
      info = MatSetValuesLocal(hes,1,&row,k,col,v,INSERT_VALUES); CHKERRQ(info);
       
    }

  }

  /* 
     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.
  */
  info = MatAssemblyBegin(hes,MAT_FINAL_ASSEMBLY); CHKERRQ(info);
  info = MatAssemblyEnd(hes,MAT_FINAL_ASSEMBLY); CHKERRQ(info);

  /*
    Tell the matrix we will never add a new nonzero location to the
    matrix. If we do it will generate an error.
  */
  info = MatSetOption(hes,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE); CHKERRQ(info);
  info = MatSetOption(hes,MAT_SYMMETRIC,PETSC_TRUE); CHKERRQ(info);

  info = PetscLogFlops(9*xm*ym+49*xm); CHKERRQ(info);

  return 0;
}
예제 #26
0
int FormFunctionGradient(TAO_APPLICATION taoapp, Vec X, double *fcn,Vec G,void *ptr)
{
  AppCtx* user=(AppCtx*)ptr;
  int info;
  PetscInt i,j,k,kk;
  PetscInt col[5],row,nx,ny,xs,xm,gxs,gxm,ys,ym,gys,gym;
  PetscReal one=1.0, two=2.0, six=6.0,pi=4.0*atan(1.0);
  PetscReal hx,hy,hxhy,hxhx,hyhy;
  PetscReal xi,v[5];
  PetscReal ecc=user->ecc, trule1,trule2,trule3,trule4,trule5,trule6;
  PetscReal vmiddle, vup, vdown, vleft, vright;
  PetscReal tt,f1,f2;
  PetscReal *x,*g,zero=0.0;
  Vec localX;

  nx=user->nx;
  ny=user->ny;
  hx=two*pi/(nx+1.0);
  hy=two*user->b/(ny+1.0);
  hxhy=hx*hy;
  hxhx=one/(hx*hx);
  hyhy=one/(hy*hy);

  info = DAGetLocalVector(user->da,&localX);CHKERRQ(info);

  info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info);
  info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info);

  info = VecSet(G, zero); CHKERRQ(info);
  /*
    Get local grid boundaries
  */
  info = DAGetCorners(user->da,&xs,&ys,TAO_NULL,&xm,&ym,TAO_NULL); CHKERRQ(info);
  info = DAGetGhostCorners(user->da,&gxs,&gys,TAO_NULL,&gxm,&gym,TAO_NULL); CHKERRQ(info);
  
  info = VecGetArray(localX,&x); CHKERRQ(info);
  info = VecGetArray(G,&g); CHKERRQ(info);

  for (i=xs; i< xs+xm; i++){
    xi=(i+1)*hx;
    trule1=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi,ecc) ) / six; /* L(i,j) */
    trule2=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi,ecc) ) / six; /* U(i,j) */
    trule3=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi+hx,ecc) ) / six; /* U(i+1,j) */
    trule4=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi-hx,ecc) ) / six; /* L(i-1,j) */
    trule5=trule1; /* L(i,j-1) */
    trule6=trule2; /* U(i,j+1) */

    vdown=-(trule5+trule2)*hyhy;
    vleft=-hxhx*(trule2+trule4);
    vright= -hxhx*(trule1+trule3);
    vup=-hyhy*(trule1+trule6);
    vmiddle=(hxhx)*(trule1+trule2+trule3+trule4)+hyhy*(trule1+trule2+trule5+trule6);

    for (j=ys; j<ys+ym; j++){
      
      row=(j-gys)*gxm + (i-gxs);
       v[0]=0; v[1]=0; v[2]=0; v[3]=0; v[4]=0;
       
       k=0;
       if (j>gys){ 
	 v[k]=vdown; col[k]=row - gxm; k++;
       }
       
       if (i>gxs){
	 v[k]= vleft; col[k]=row - 1; k++;
       }

       v[k]= vmiddle; col[k]=row; k++;
       
       if (i+1 < gxs+gxm){
	 v[k]= vright; col[k]=row+1; k++;
       }
       
       if (j+1 <gys+gym){
	 v[k]= vup; col[k] = row+gxm; k++;
       }
       tt=0;
       for (kk=0;kk<k;kk++){
	 tt+=v[kk]*x[col[kk]];
       }
       row=(j-ys)*xm + (i-xs);
       g[row]=tt;

     }

  }

  info = VecRestoreArray(localX,&x); CHKERRQ(info);
  info = VecRestoreArray(G,&g); CHKERRQ(info);

  info = DARestoreLocalVector(user->da,&localX); CHKERRQ(info);

  info = VecDot(X,G,&f1); CHKERRQ(info);
  info = VecDot(user->B,X,&f2); CHKERRQ(info);
  info = VecAXPY(G, one, user->B); CHKERRQ(info);
  *fcn = f1/2.0 + f2;

  info = PetscLogFlops((91 + 10*ym) * xm); CHKERRQ(info);
  return 0;

}
예제 #27
0
/* 
   Visualize solutions
*/
PetscErrorCode MySolutionView(MPI_Comm comm,PetscInt phy_num,void *ctx)
{
  PetscErrorCode ierr;
  AppCtx         *user = (AppCtx*)ctx;
  DMMG           *dmmg = user->dmmg;
  DA             da=DMMGGetDA(dmmg);
  Field          **x = user->x;
  Field1         **x1 = user->x1;
  PetscInt       i,j,mx,xs,ys,xm,ym;
  PetscMPIInt    size;

  PetscFunctionBegin;
  ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
  ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr);
  
  switch (phy_num){
  case 0:
    if (size == 1){
      ierr = PetscPrintf(PETSC_COMM_SELF,"Original Physics %d U,V,Omega,Temp: \n",phy_num);
      ierr = PetscPrintf(PETSC_COMM_SELF,"-----------------------------------\n");
      for (j=ys; j<ys+ym; j++) {
        for (i=xs; i<xs+xm; i++) {
          ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g, %g, %g, %g\n",j,i,x[j][i].u,x[j][i].v,x[j][i].omega,x[j][i].temp);
        }
      }    
    }
    break;
  case 1:
    if (size == 1){
      ierr = PetscPrintf(PETSC_COMM_SELF,"SubPhysics %d: U,V,Omega: \n",phy_num);
      ierr = PetscPrintf(PETSC_COMM_SELF,"------------------------\n");
      DMMG *dmmg1=user->dmmg1;
      Vec  solu_true = DMMGGetx(dmmg1);
      DA   da=DMMGGetDA(dmmg1);
      Field1 **x1;
      ierr = DAVecGetArray(da,solu_true,&x1);CHKERRQ(ierr);
      for (j=ys; j<ys+ym; j++) {
        for (i=xs; i<xs+xm; i++) {
          ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g, %g, %g\n",j,i,x1[j][i].u,x1[j][i].v,x1[j][i].omega);
        }
      } 
      ierr = DAVecRestoreArray(da,solu_true,&x1);CHKERRQ(ierr);
    }
    break;
  case 2:
    if (size == 1){
      ierr = PetscPrintf(PETSC_COMM_SELF,"SubPhysics %d: Temperature: \n",phy_num);
      ierr = PetscPrintf(PETSC_COMM_SELF,"--------------------------\n");
      DMMG *dmmg2=user->dmmg2;
      Vec  solu_true = DMMGGetx(dmmg2);
      DA   da=DMMGGetDA(dmmg2);
      Field2 **x2;
      ierr = DAVecGetArray(da,solu_true,&x2);CHKERRQ(ierr);
      for (j=ys; j<ys+ym; j++) {
        for (i=xs; i<xs+xm; i++) {
          ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g\n",j,i,x2[j][i].temp);
        }
      } 
      ierr = DAVecRestoreArray(da,solu_true,&x2);CHKERRQ(ierr);
    }
    break;
  default:
    if (size == 1){
      DMMG        *dmmg_comp=user->dmmg_comp;
      DA          da1,da2,da=DMMGGetDA(dmmg);
      Vec         X1,X2,solu_true = DMMGGetx(dmmg);
      Field       **x;
      Field1      **x1;
      Field2      **x2;
      DMComposite dm = (DMComposite)(*dmmg_comp)->dm;
      PetscReal   err,err_tmp;
      if (phy_num == 3){
        ierr = PetscPrintf(PETSC_COMM_SELF,"Composite physics %d, U,V,Omega,Temp: \n",phy_num);
        ierr = PetscPrintf(PETSC_COMM_SELF,"------------------------------------\n");
        ierr = PetscPrintf(PETSC_COMM_SELF,"Composite physics, U,V,Omega,Temp: \n");CHKERRQ(ierr);
      }
      ierr = DAVecGetArray(da,solu_true,&x);CHKERRQ(ierr);
      ierr = DMCompositeGetEntries(dm,&da1,&da2);CHKERRQ(ierr);
      ierr = DMCompositeGetLocalVectors(dm,&X1,&X2);CHKERRQ(ierr);
      ierr = DAVecGetArray(da1,X1,(void**)&x1);CHKERRQ(ierr);
      ierr = DAVecGetArray(da2,X2,(void**)&x2);CHKERRQ(ierr);

      err = 0.0;
      for (j=ys; j<ys+ym; j++) {
        for (i=xs; i<xs+xm; i++) {
          err_tmp = PetscAbs(x[j][i].u-x1[j][i].u) + PetscAbs(x[j][i].v-x1[j][i].v) + PetscAbs(x[j][i].omega-x1[j][i].omega);
          err_tmp += PetscAbs(x[j][i].temp-x2[j][i].temp);
          if (err < err_tmp) err = err_tmp; 
          if (phy_num == 3){
            ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g, %g, %g, %g\n",j,i,x1[j][i].u,x1[j][i].v,x1[j][i].omega,x2[j][i].temp);
          }
        }
      }
      ierr = PetscPrintf(PETSC_COMM_SELF,"|solu - solu_comp| =  %g\n",err);CHKERRQ(ierr);
      ierr = DAVecRestoreArray(da1,X1,(void**)&x1);CHKERRQ(ierr);
      ierr = DAVecRestoreArray(da2,X2,(void**)&x2);CHKERRQ(ierr);
      ierr = DMCompositeRestoreLocalVectors(dm,&X1,&X2);CHKERRQ(ierr);
      ierr = DAVecRestoreArray(da,solu_true,&x);CHKERRQ(ierr);
    }
  }
  PetscFunctionReturn(0);
}
예제 #28
0
파일: Production.c 프로젝트: yye00/Defiant
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);
}
예제 #29
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;
}
예제 #30
0
int main(int argc,char **args)
{
  PetscInt       rank,size,npt;  
  PetscScalar    dx,dy,cx,cy;
  PetscErrorCode ierr;
  Vec            x,x0,tempvec, *vinda,*vindb,*vindc;
  PetscInt       i,j,k,n,n2,pmax,puse,Istart,Iend,localsize,niter;
  PetscScalar    **x0array, **aarray,**barray;
  PetscInt       *cacheInt;
  PetscScalar    *cacheScalar;  
  DA             myDA;

  PetscScalar    *Mixnorm;
  PetscInt       iter,*iterind,*nind;
  FILE           *fidoutput, *fidtimelog;   
  char           fname[50],ftimelog[50];
  PetscViewer    socketviewer; 
  PetscInt       withMatlab, doFFT, doSmoothing;
  PetscTruth     Matlabflag, FFTflag, Smoothingflag;
  PetscInt       timelogcount;  
  MPI_Status     status;

  PetscLogDouble v1,v2,elapsed_time;
  timelogcount = 0;
 
 
  PetscInitialize(&argc,&args,(char *)0,help);
  MPI_Comm_size(PETSC_COMM_WORLD,&size);
  MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

  ierr = PetscPrintf(PETSC_COMM_WORLD,"\nPETSC: Petsc Initializes successfully! \n");
  ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: comm_size is %d \n", size);
 
  ierr = PetscOptionsGetInt(PETSC_NULL,"-withMatlab",&withMatlab,&Matlabflag);CHKERRQ(ierr);  
  if (Matlabflag == PETSC_FALSE){withMatlab = 0;}else{withMatlab = 1;}
  ierr = PetscOptionsGetInt(PETSC_NULL,"-doFFT",&doFFT,&FFTflag);CHKERRQ(ierr);  
  if (FFTflag == PETSC_FALSE){doFFT = 0;}else{doFFT = 1;}

  ierr = PetscOptionsGetInt(PETSC_NULL,"-doSmoothing",&doSmoothing,&Smoothingflag);CHKERRQ(ierr);  
  if (Smoothingflag == PETSC_FALSE){doSmoothing = 0;}else{doSmoothing = 1;}

  if(withMatlab==1){
  // Rank 0 connects to socket, use default socket
  PetscViewerSocketOpen(PETSC_COMM_WORLD,0,PETSC_DEFAULT,&socketviewer);  
  ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: socket opened! \n");CHKERRQ(ierr); 

  // Receive n from Matlab
  IntReceive(socketviewer, &nind);
  n = *nind;
  //  Receive iter from Matlab
  IntReceive(socketviewer, &iterind);
  iter = *iterind;
 
  }else{
  ierr = PetscOptionsGetInt(PETSC_NULL,"-ngrid",&n,PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscOptionsGetInt(PETSC_NULL,"-niter",&iter,PETSC_NULL);CHKERRQ(ierr);
  }

  
 
/////////////////////////////////////////////////////////////////////////////////////

  ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: number of grid is %d \n", n);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: number of iteration is %d \n", iter);


  Mixnorm    = malloc(iter*sizeof(PetscScalar));

  dx         = 1.0/n;
  dy         = 1.0/n;
  n2         = (PetscInt)(n*0.5);
  npt        = 5;
  pmax       = 5e5;
  puse       = pmax;


  PetscInt      logmax = 1000;
  PetscScalar   Timelog[logmax];
  PetscLogDouble t1,t2;

  ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: estimated buffer size (per processer) %f Mbytes \n", pmax*1.0/1e6*8*17 );
  ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: estimated variable size %f Mbytes\n", 1.0*n*n/1e6*8*1);

/////////////////////////////////////////////////////////////////////////////////////
  
 // ierr  = VecCreateMPI(PETSC_COMM_WORLD,PETSC_DECIDE ,n,&tempvec);CHKERRQ(ierr);
 // ierr  = VecGetOwnershipRange(tempvec,&Istart,&Iend);CHKERRQ(ierr); 
 // localsize = Iend-Istart;
 // ierr = VecDestroy(tempvec);CHKERRQ(ierr);


/////////////////////////////////////////////////////////////////////////////////////

if(doSmoothing==1){
      ierr = PetscPrintf(PETSC_COMM_WORLD,"\n\n\n\n\nPETSC: Now Do  DACreate2d \n\n\n\n" );
      ierr = PetscPrintf(PETSC_COMM_WORLD,"\n\n\n\n\nPETSC: %d  %d  %d\n\n\n\n",n2,n,size);
      DACreate2d(MPI_COMM_WORLD,DA_XYPERIODIC,DA_STENCIL_BOX,n2,n,1,size,1,2,PETSC_NULL,PETSC_NULL,&myDA);
      DACreateGlobalVector(myDA,&x0);
      DAGetCorners(myDA,PETSC_NULL,&Istart,PETSC_NULL,PETSC_NULL,&localsize,PETSC_NULL);
      Iend = Istart+localsize;
}else{
      ierr  = VecCreateMPI(PETSC_COMM_WORLD,PETSC_DECIDE ,n,&tempvec);CHKERRQ(ierr);
      ierr  = VecGetOwnershipRange(tempvec,&Istart,&Iend);CHKERRQ(ierr); 
      localsize = Iend-Istart;
      ierr = VecDestroy(tempvec);CHKERRQ(ierr);
      VecCreateMPI(PETSC_COMM_WORLD,localsize*n2,PETSC_DETERMINE ,&x0);
}


//ierr = PetscPrintf(PETSC_COMM_WORLD,"\n\n\n\n\nPETSC: So far so good\n\n\n\n");



VecGetArray2d(x0,n2,localsize,0,0,&x0array);

// Create initial vector

   
   for(j=0;j<localsize;j++){
         for(i=0;i<n2;i++){
             cx = (Istart+j+0.5)*dx;  
             x0array[i][j] = cos(2*M_PI*cx);
        }
    }

    
VecRestoreArray2d(x0,n2,localsize,0,0,&x0array);


    ierr = VecDuplicate(x0,&x);CHKERRQ(ierr); 
    ierr =  VecNorm(x0,NORM_2,Mixnorm); CHKERRQ(ierr);  
    PetscPrintf(PETSC_COMM_WORLD,"PETSC: initial norm= %f \n",*(Mixnorm+0)/n ); 
    vinda = &x0;
    vindb = &x;

    sprintf(fname, "mixnorm_%d_%d",n,iter);
    ierr =PetscPrintf(PETSC_COMM_WORLD,"\n iter     norm      time      unit time\n");CHKERRQ(ierr);
    ierr =PetscFOpen(PETSC_COMM_WORLD,fname,"w",&fidoutput);CHKERRQ(ierr);

///////////////////////////////////////////////////////////////////////////////////////////////////
// Memory allocation for the iteration scheme 

 //   cacheInt    = malloc(1*pmax*sizeof(PetscInt));
 //   cacheScalar = malloc(2*pmax*sizeof(PetscScalar));

   cacheInt    = malloc(2*pmax*sizeof(PetscInt));
   cacheScalar = malloc(2*pmax*sizeof(PetscScalar));
///////////////////////////////////////////////////////////////////////////////////////////////////
// Iteration here!

for(niter=0;niter<iter;niter++){

  ierr = PetscGetTime(&v1);CHKERRQ(ierr);
 // BackwardAverage(vinda, vindb, cacheInt, cacheScalar, n,  npt, pmax, Istart,Iend);
 // BackwardAverageR(vinda, vindb, cacheInt, cacheScalar, n,  npt, pmax, Istart,Iend);
   BackwardAverageRL(vinda, vindb, cacheInt, cacheScalar, n,  npt, pmax, Istart,Iend);
   vindc = vindb;
   vindb = vinda;
   vinda = vindc;   
// if(doSmoothing==1){Smoothing(vinda, vindb,n, myDA, Istart,Iend);}
  ierr = PetscGetTime(&v2);CHKERRQ(ierr);
   //vindc = vindb;
   //vindb = vinda;
   //vinda = vindc;   
  
   ierr =  VecNorm(*vinda,NORM_2,Mixnorm+niter); CHKERRQ(ierr); 
   *(Mixnorm+niter) = *(Mixnorm+niter)/n; 
      
   elapsed_time = v2 - v1; 
   PetscPrintf(PETSC_COMM_WORLD,"     %d   %f   %f  %f \n",niter,*(Mixnorm+niter),elapsed_time,elapsed_time/n/n*1e6 );
   PetscFPrintf(PETSC_COMM_WORLD,fidoutput,"    %d   %f   %f  %f\n"
                ,niter,*(Mixnorm+niter),elapsed_time,elapsed_time/n/n*1e6 ); 
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//Change oremtation of vector
VecGetArray2d(*vinda,n2,localsize,0,0,&aarray);
VecGetArray2d(*vindb,localsize,n2,0,0,&barray);
  for(j=0;j<localsize;j++){
       for(i=0;i<n2;i++){
             barray[j][i] = aarray[i][j];       
        }
    }  
VecRestoreArray2d(*vinda,n2,localsize,0,0,&aarray);
VecRestoreArray2d(*vindb,localsize,n2,0,0,&barray);
   vindc = vindb;
   vindb = vinda;
   vinda = vindc;  

////////////////////////////////////////////////////////////////////////////////////////////////////
// FFT part
if(doFFT==1){FFT2D(*vinda,*vindb, localsize, n, Istart,Iend, iter,doSmoothing);}
////////////////////////////////////////////////////////////////////////////////////////////////////
/*
   if(rank==0){
   sprintf(ftimelog, "timelog_%d_%d",n,iter);
   fidtimelog = fopen(ftimelog,"w");
   for(i=0;i<timelogcount;i++){  fprintf(fidtimelog,"%f ",Timelog[i]); }  
   fprintf(fidtimelog,"\n ");  

   for(j = 1;j<size;j++){
     MPI_Recv(Timelog,timelogcount,MPI_DOUBLE,j,j,PETSC_COMM_WORLD,&status);
      for(i=0;i<timelogcount;i++){  fprintf(fidtimelog,"%f ",Timelog[i]); }
      fprintf(fidtimelog,"\n ");
     }
   fclose(fidtimelog);
   }else{ 
   MPI_Send(Timelog ,timelogcount,MPI_DOUBLE,0,rank,PETSC_COMM_WORLD);
   } 
   PetscFClose(PETSC_COMM_WORLD,fidoutput);
*/ 
///////////////////////////////////////////////////////////////////////////

    if(withMatlab==1){
     VecView(*vinda,socketviewer);
     PetscScalarView(iter,Mixnorm,socketviewer);
    }
 

  // free(x0array); 
   free(Mixnorm);
   free(cacheInt);
   free(cacheScalar);
 
   ierr = VecDestroy(x0);CHKERRQ(ierr);
   ierr = VecDestroy(x);CHKERRQ(ierr);
   
 
  PetscPrintf(PETSC_COMM_WORLD,"Done!");
  
//////////////////////////////////////////////////////////////////////////////////////
  ierr = PetscFinalize();CHKERRQ(ierr);