Exemple #1
0
PetscErrorCode FluidFieldDivergence(FluidField f)
{
  DALocalInfo info;
  Vec u,v,w; // Local, ghosted vectors
  PetscErrorCode ierr;
  
  PetscFunctionBegin;
  PetscLogEventBegin(EVENT_FluidFieldDivergence,0,0,0,0);
//  PetscLogEventRegister(&EVENT_FluidFieldDivergence,"FluidFieldDivergence", 0);
  ierr = DAGetLocalInfo(f->da,&info); CHKERRQ(ierr);
  ierr = DAGetLocalVector(f->da,&u); CHKERRQ(ierr);
  ierr = DAGetLocalVector(f->da,&v); CHKERRQ(ierr);
  ierr = DAGlobalToLocalBegin(f->da,f->u,INSERT_VALUES,u); CHKERRQ(ierr);
  ierr = DAGlobalToLocalEnd(  f->da,f->u,INSERT_VALUES,u); CHKERRQ(ierr);
  ierr = DAGlobalToLocalBegin(f->da,f->v,INSERT_VALUES,v); CHKERRQ(ierr);
  //TODO: interleaving work with communication here a possible source of optimization?
  ierr = DAGlobalToLocalEnd(  f->da,f->v,INSERT_VALUES,v); CHKERRQ(ierr);
  
  if( f->is3D )
  {
    ierr = DAGetLocalVector(f->da,&w); CHKERRQ(ierr);
    ierr = DAGlobalToLocalBegin(f->da,f->w,INSERT_VALUES,w); CHKERRQ(ierr);
    ierr = DAGlobalToLocalEnd(  f->da,f->w,INSERT_VALUES,w); CHKERRQ(ierr);
    FluidFieldDivergence_3D(info, f->d, u, v, w, f->div);
    ierr = DARestoreLocalVector(f->da,&w); CHKERRQ(ierr);
  } else {
    FluidFieldDivergence_2D(info, f->d, u, v, f->div);
  }
  ierr = DARestoreLocalVector(f->da,&u); CHKERRQ(ierr);
  ierr = DARestoreLocalVector(f->da,&v); CHKERRQ(ierr);
  
  PetscLogEventEnd(EVENT_FluidFieldDivergence,0,0,0,0);
  PetscFunctionReturn(0);
}
Exemple #2
0
PetscErrorCode FormFunction(SNES snes,Vec X,Vec F,void *ctx)
{
  PetscErrorCode ierr;
  DMMG           dmmg = (DMMG)ctx;
  AppCtx         *user = (AppCtx*)dmmg->user;
  DA             da2 = (DA)dmmg->dm;
  DALocalInfo    info2;
  Field2         **x2,**f2;
  Vec            X2;

  PetscFunctionBegin;
  ierr = DAGetLocalInfo(da2,&info2);CHKERRQ(ierr);

  /* Get local vectors to hold ghosted parts of X */
  ierr = DAGetLocalVector(da2,&X2);CHKERRQ(ierr);
  ierr = DAGlobalToLocalBegin(da2,X,INSERT_VALUES,X2);CHKERRQ(ierr); 
  ierr = DAGlobalToLocalEnd(da2,X,INSERT_VALUES,X2);CHKERRQ(ierr); 

  /* Access the array inside of X1 */
  ierr = DAVecGetArray(da2,X2,(void**)&x2);CHKERRQ(ierr);

  /* Access the subvectors in F. 
     These are not ghosted so directly access the memory locations in F */
  ierr = DAVecGetArray(da2,F,(void**)&f2);CHKERRQ(ierr);

  /* Evaluate local user provided function */    
  ierr = FormFunctionLocal2(&info2,0,x2,f2,(void**)user);CHKERRQ(ierr);

  ierr = DAVecRestoreArray(da2,F,(void**)&f2);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(da2,X2,(void**)&x2);CHKERRQ(ierr);
  ierr = DARestoreLocalVector(da2,&X2);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #3
0
int main(int argc,char **argv)
{
  PetscErrorCode ierr;
  PetscViewer    viewer;
  DA             da;
  Vec            global,local,global2;
  PetscMPIInt    rank;
  PetscTruth     flg;

  /*
    Every PETSc routine should begin with the PetscInitialize() routine.
    argc, argv - These command line arguments are taken to extract the options
                 supplied to PETSc and options supplied to MPI.
    help       - When PETSc executable is invoked with the option -help, 
                 it prints the various options that can be applied at 
                 runtime.  The user can use the "help" variable place
                 additional help messages in this printout.
  */
  ierr = PetscInitialize(&argc,&argv,(char *)0,help);CHKERRQ(ierr);

  /* Create a DA and an associated vector */
  ierr = DACreate2d(PETSC_COMM_WORLD,DA_NONPERIODIC,DA_STENCIL_BOX,100,90,PETSC_DECIDE,PETSC_DECIDE,2,1,PETSC_NULL,PETSC_NULL,&da);CHKERRQ(ierr);
  ierr = DACreateGlobalVector(da,&global);CHKERRQ(ierr);
  ierr = DACreateLocalVector(da,&local);CHKERRQ(ierr);
  ierr = VecSet(global,-1.0);CHKERRQ(ierr);
  ierr = DAGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
  ierr = DAGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
  ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
  ierr = VecScale(local,rank+1);CHKERRQ(ierr);
  ierr = DALocalToGlobal(da,local,ADD_VALUES,global);CHKERRQ(ierr);

  /* 
     Write output file with PetscViewerHDF5 viewer. 

  */
  ierr = PetscViewerHDF5Open(PETSC_COMM_WORLD,"hdf5output",FILE_MODE_WRITE,&viewer); CHKERRQ(ierr);
  ierr = VecView(global,viewer);CHKERRQ(ierr);
  ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
  
  ierr = VecDuplicate(global,&global2);CHKERRQ(ierr);
  ierr = VecCopy(global,global2);CHKERRQ(ierr);
  ierr = PetscViewerHDF5Open(PETSC_COMM_WORLD,"hdf5output",FILE_MODE_READ,&viewer); CHKERRQ(ierr);
  ierr = VecLoadIntoVector(viewer,global);CHKERRQ(ierr);
  ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
  ierr = VecEqual(global,global2,&flg);CHKERRQ(ierr);
  if (flg) {
    ierr = PetscPrintf(PETSC_COMM_WORLD,"Vectors are equal\n");CHKERRQ(ierr);
  } else {
    ierr = PetscPrintf(PETSC_COMM_WORLD,"Vectors are not equal\n");CHKERRQ(ierr);
  }

  /* clean up and exit */
  ierr = DADestroy(da);CHKERRQ(ierr);
  ierr = VecDestroy(local);CHKERRQ(ierr);
  ierr = VecDestroy(global);CHKERRQ(ierr);
  ierr = VecDestroy(global2);CHKERRQ(ierr);
  ierr = PetscFinalize();CHKERRQ(ierr);
  return 0;  
}
Exemple #4
0
PetscErrorCode equation(SNES snes, Vec soln_vec, Vec fun_vec, void* ptr)
{
	//data structure will be contained in ptr
	Data* data = (Data*) ptr;
	Params P = data->P;
	DA da = data->da;

	DALocalInfo info;
	PetscFunctionBegin;

	DAGetLocalInfo(da, &info);
	Vec sv_local; //need local vector containing ghost point information

	DACreateLocalVector(da, &sv_local);
	DAGlobalToLocalBegin(da, soln_vec, INSERT_VALUES, sv_local);
	DAGlobalToLocalEnd(da, soln_vec, INSERT_VALUES, sv_local);

	//to evaluate fuction, the sv_local soln_vec need to be converted into Field arrays
	Field **X;
	Field **F;

	DAVecGetArray(da, sv_local, &X);
	DAVecGetArray(da, fun_vec, &F);
	//since sv_local is local vector, X will have access to ghost points
	
	PetscInt i, j, Ny = P.Ny;
	PetscScalar hx = P.hx; hy = P.hy; x, y;

	for(i=info.xs; i<info.xs + info.xm; i++){
		for(j=info.ys; j<info.ys+info.ym; j++){
			x = i *hx;
			y = j *hy;

			if(j==0) {
				F[j][i].u = X[j][i].u - 0.5*(sin(2*PETSC_PI*x) + 1);
				F[j][i].v = X[j][i].v ;
			}
			else if (j== Ny-1){
				F[j][i].u = X[j][i].u;
				F[j][i].v = X[j][i].v - 0.5*(sin(2*PETSC_PI*x) + 1);
			}
			else {
				F[j][i].u = lap(u) + X[j][i].u * X[j][i].v ;
				F[j][i].v = lap(v) - X[j][i].u * X[j][i].v ;
			}
		}
	}

	DAVecRestoreArray(da, fun_vec, &F);
	DAVecRestoreArray(da, sv_local, &X);

	VecDestory(sv_local);

	PetscFuntionReturn(0);
}
Exemple #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; 
}
Exemple #6
0
PetscErrorCode ComputeFunction(SNES snes,Vec x,Vec f,void *ctx) {
  PetscInt i,Mx,xs,xm; PetscScalar *xx,*ff,hx; DA da = (DA) ctx; Vec xlocal;
  DAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
  hx     = 1.0/(PetscReal)(Mx-1);
  DAGetLocalVector(da,&xlocal);DAGlobalToLocalBegin(da,x,INSERT_VALUES,xlocal);  DAGlobalToLocalEnd(da,x,INSERT_VALUES,xlocal);
  DAVecGetArray(da,xlocal,&xx); DAVecGetArray(da,f,&ff);
  DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);

  for (i=xs; i<xs+xm; i++) {
    if (i == 0 || i == Mx-1) ff[i] = xx[i]/hx; 
    else  ff[i] =  (2.0*xx[i] - xx[i-1] - xx[i+1])/hx - hx*PetscExpScalar(xx[i]); 
  }
  DAVecRestoreArray(da,xlocal,&xx); DARestoreLocalVector(da,&xlocal);DAVecRestoreArray(da,f,&ff);
  return 0;}
Exemple #7
0
static PetscErrorCode TestQ2Q1DA( void )
{
  DA             Q2_da,Q1_da,cda;
  PetscInt       mx,my,mz;
  Vec            coords,gcoords,gcoords2;
  PetscErrorCode ierr;

  mx=7;
  my=11;
  mz=13;
  ierr=DACreate3d(PETSC_COMM_WORLD,DA_NONPERIODIC,DA_STENCIL_BOX,mx,my,mz,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,3,2,0,0,0,&Q2_da);CHKERRQ(ierr);
  ierr = DASetUniformCoordinates(Q2_da,-1.0,1.0,-2.0,2.0,-3.0,3.0);CHKERRQ(ierr);
  ierr = DAGetCoordinates(Q2_da,&coords);CHKERRQ(ierr);
  ierr = DACreate3d(PETSC_COMM_WORLD,DA_NONPERIODIC,DA_STENCIL_BOX,mx,my,mz,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,3,1,0,0,0,&Q1_da);CHKERRQ(ierr);
  ierr = DASetCoordinates(Q1_da,coords);CHKERRQ(ierr);
  ierr = VecDestroy(coords);CHKERRQ(ierr);

  /* Get ghost coordinates one way */
  ierr = DAGetGhostedCoordinates(Q1_da,&gcoords);CHKERRQ(ierr);

  /* And another */
  ierr = DAGetCoordinates(Q1_da,&coords);CHKERRQ(ierr);
  ierr = DAGetCoordinateDA(Q1_da,&cda);CHKERRQ(ierr);
  ierr = DAGetLocalVector(cda,&gcoords2);CHKERRQ(ierr);
  ierr = DAGlobalToLocalBegin(cda,coords,INSERT_VALUES,gcoords2);CHKERRQ(ierr);
  ierr = DAGlobalToLocalEnd(cda,coords,INSERT_VALUES,gcoords2);CHKERRQ(ierr);

  ierr = CompareGhostedCoords(gcoords,gcoords2);CHKERRQ(ierr);
  ierr = DARestoreLocalVector(cda,&gcoords2);CHKERRQ(ierr);
  ierr = DADestroy(cda);CHKERRQ(ierr);

  ierr = VecScale(coords,10.0);CHKERRQ(ierr);
  ierr = VecScale(gcoords,10.0);CHKERRQ(ierr);
  ierr = DAGetGhostedCoordinates(Q1_da,&gcoords2);CHKERRQ(ierr);
  ierr = CompareGhostedCoords(gcoords,gcoords2);CHKERRQ(ierr);
  ierr = VecDestroy(coords);CHKERRQ(ierr);
  ierr = VecDestroy(gcoords2);CHKERRQ(ierr);

  ierr = VecDestroy(gcoords);CHKERRQ(ierr);
  ierr = DADestroy(Q2_da);CHKERRQ(ierr);
  ierr = DADestroy(Q1_da);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #8
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;}
Exemple #9
0
PetscErrorCode FormFunction1(SNES snes,Vec X,Vec F,void *ctx) 
{
  PetscErrorCode ierr;
  DMMG           dmmg = (DMMG)ctx;
  AppCtx         *user = (AppCtx*)dmmg->user;
  DA             da1 = (DA)dmmg->dm;
  DALocalInfo    info1;
  Field1         **x1,**f1;
  Vec            X1;
  Field2         **x2;

  PetscFunctionBegin;
  ierr = DAGetLocalInfo(da1,&info1);CHKERRQ(ierr);

  /* Get local vectors to hold ghosted parts of X */
  ierr = DAGetLocalVector(da1,&X1);CHKERRQ(ierr);
  ierr = DAGlobalToLocalBegin(da1,X,INSERT_VALUES,X1);CHKERRQ(ierr); 
  ierr = DAGlobalToLocalEnd(da1,X,INSERT_VALUES,X1);CHKERRQ(ierr); 

  /* Access the arrays inside X1 */
  ierr = DAVecGetArray(da1,X1,(void**)&x1);CHKERRQ(ierr);

  /* Access the subvectors in F. 
     These are not ghosted so directly access the memory locations in F */
  ierr = DAVecGetArray(da1,F,(void**)&f1);CHKERRQ(ierr);

  /* Evaluate local user provided function */   
  if (user->nsolve){
    x2 = user->x2;
    ierr = FormFunctionLocal1(&info1,x1,x2,f1,(void**)user);CHKERRQ(ierr);
  } else {
    ierr = FormFunctionLocal1(&info1,x1,0,f1,(void**)user);CHKERRQ(ierr);
  }


  ierr = DAVecRestoreArray(da1,F,(void**)&f1);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(da1,X1,(void**)&x1);CHKERRQ(ierr);
  ierr = DARestoreLocalVector(da1,&X1);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #10
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;
}
Exemple #11
0
int main(int argc,char **argv)
{
  PetscMPIInt    rank;
  PetscInt       M = -10,N = -8;
  PetscErrorCode ierr;
  PetscTruth     flg = PETSC_FALSE;
  DA             da;
  PetscViewer    viewer;
  Vec            local,global;
  PetscScalar    value;
  DAPeriodicType ptype = DA_NONPERIODIC;
  DAStencilType  stype = DA_STENCIL_BOX;
#if defined(PETSC_HAVE_MATLAB_ENGINE)
  PetscViewer    mviewer;
#endif

  ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); 
  ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",300,0,300,300,&viewer);CHKERRQ(ierr);
#if defined(PETSC_HAVE_MATLAB_ENGINE)
  ierr = PetscViewerMatlabOpen(PETSC_COMM_WORLD,"tmp.mat",FILE_MODE_WRITE,&mviewer);CHKERRQ(ierr);
#endif

  ierr = PetscOptionsGetTruth(PETSC_NULL,"-star_stencil",&flg,PETSC_NULL);CHKERRQ(ierr);
  if (flg) stype = DA_STENCIL_STAR;
      
  /* Create distributed array and get vectors */
  ierr = DACreate2d(PETSC_COMM_WORLD,ptype,stype,M,N,PETSC_DECIDE,PETSC_DECIDE,1,1,PETSC_NULL,PETSC_NULL,&da);CHKERRQ(ierr);
  ierr = DACreateGlobalVector(da,&global);CHKERRQ(ierr);
  ierr = DACreateLocalVector(da,&local);CHKERRQ(ierr);

  value = -3.0;
  ierr = VecSet(global,value);CHKERRQ(ierr);
  ierr = DAGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
  ierr = DAGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr);

  ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
  value = rank+1;
  ierr = VecScale(local,value);CHKERRQ(ierr);
  ierr = DALocalToGlobal(da,local,ADD_VALUES,global);CHKERRQ(ierr);
  
  flg  = PETSC_FALSE;
  ierr = PetscOptionsGetTruth(PETSC_NULL, "-view_global", &flg,PETSC_NULL);CHKERRQ(ierr);
  if (flg) { /* view global vector in natural ordering */
    ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  }
  ierr = DAView(da,viewer);CHKERRQ(ierr);
  ierr = VecView(global,viewer);CHKERRQ(ierr);
#if defined(PETSC_HAVE_MATLAB_ENGINE)
  ierr = DAView(da,mviewer);CHKERRQ(ierr);
  ierr = VecView(global,mviewer);CHKERRQ(ierr);
#endif

  /* Free memory */
#if defined(PETSC_HAVE_MATLAB_ENGINE)
  ierr = PetscViewerDestroy(mviewer);CHKERRQ(ierr);
#endif
  ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
  ierr = VecDestroy(local);CHKERRQ(ierr);
  ierr = VecDestroy(global);CHKERRQ(ierr);
  ierr = DADestroy(da);CHKERRQ(ierr);
  ierr = PetscFinalize();CHKERRQ(ierr);
  return 0;
}
Exemple #12
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;
}
Exemple #13
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;
}
Exemple #14
0
void Solve_Distance_Explicit(UserCtx *user)
{
	DALocalInfo	info;
	PetscInt	xs,	xe,	ys,	ye,	zs,	ze;	// Local grid	information
	PetscInt	mx,	my,	mz;	// Dimensions	in three directions
	PetscInt	i, j,	k;
	PetscInt	lxs, lxe,	lys, lye,	lzs, lze;
	PetscReal	***level;

	DAGetLocalInfo(user->da, &info);
	mx = info.mx;	my = info.my;	mz = info.mz;
	xs = info.xs;	xe = xs	+	info.xm;
	ys = info.ys;	ye = ys	+	info.ym;
	zs = info.zs;	ze = zs	+	info.zm;

	lxs	=	xs;	lxe	=	xe;
	lys	=	ys;	lye	=	ye;
	lzs	=	zs;	lze	=	ze;

	if (xs==0) lxs = xs+1;
	if (ys==0) lys = ys+1;
	if (zs==0) lzs = zs+1;

	if (xe==mx)	lxe	=	xe-1;
	if (ye==my)	lye	=	ye-1;
	if (ze==mz)	lze	=	ze-1;
	
	DAGlobalToLocalBegin(user->da, LevelSet, INSERT_VALUES,	user->lLevelset);
	DAGlobalToLocalEnd(user->da, LevelSet, INSERT_VALUES,	user->lLevelset);
	
	DAVecGetArray(user->da,	user->lLevelset, &level);
	
	if(xs==0 ||	xe==mx)	{
		int	from,	to;
		for	(k=lzs;	k<lze; k++)
		for	(j=lys;	j<lye; j++)	{
			if(xs==0)	{
				i	=	1, from	=	i, to	=	0;
				
				if(i_periodic) from	=	mx-2;
				else if(ii_periodic) from	=	-2;
				
				level[k][j][to]	=	level[k][j][from];
			}
			
			if(xe==mx) {
				i	=	mx-2,	from = i,	to = mx-1;
				
				if(i_periodic) from	=	1;
				else if(ii_periodic) from	=	mx+1;
				
				level[k][j][to]	=	level[k][j][from];
			}
		}
	}
	
	if(ys==0 ||	ye==my)	{
		int	from,	to;
				
		for	(k=lzs;	k<lze; k++)
		for	(i=lxs;	i<lxe; i++)	{
			if(ys==0)	{
				j	=	1, from	=	j, to	=	0;
				
				if(j_periodic) from	=	my-2;
				else if(jj_periodic) from	=	-2;
				
				level[k][to][i]	=	level[k][from][i];
			}
			
			if(ye==my) {
				j	=	my-2,	from = j,	to = my-1;
				
				if(j_periodic) from	=	1;
				else if(jj_periodic) from	=	my+1;
				
				level[k][to][i]	=	level[k][from][i];
			}
		}
	}
	
	if(zs==0 ||	ze==mz)	{
		int	from,	to;
		
		for	(j=lys;	j<lye; j++)
		for	(i=lxs;	i<lxe; i++)	{
			if(zs==0)	{
				k	=	1, from	=	k, to	=	0;
				
				if(k_periodic) from = mz-2;
				else if(kk_periodic) from = -2;
				
				level[to][j][i]	= level[from][j][i];
			}
			
			if(ze==mz) {
				k = mz-2, from = k, to = mz-1;
				
				if(k_periodic) from = 1;
				else if(kk_periodic) from = mz+1;
				
				level[to][j][i] = level[from][j][i];
			}
		}
	}
	
	DAVecRestoreArray(user->da, user->lLevelset, &level);
	
	Vec Rhs;
	VecDuplicate(user->P, &Rhs);
	Distance_Function_RHS(user, Rhs, 1);
	VecAXPY(LevelSet, dtau,	Rhs);
	VecDestroy(Rhs);
	return;
}
Exemple #15
0
void Compute_Distance_Function(UserCtx *user)
{
	DALocalInfo	info;
	PetscInt	i, j,	k;
	DAGetLocalInfo(user->da, &info);
	PetscInt	mx = info.mx,	my = info.my,	mz = info.mz;
	PetscInt	xs = info.xs,	xe = xs	+	info.xm;
	PetscInt	ys = info.ys,	ye = ys	+	info.ym;
	PetscInt	zs = info.zs,	ze = zs	+	info.zm;
	PetscInt	lxs	=	xs,	lxe	=	xe;
	PetscInt	lys	=	ys,	lye	=	ye;
	PetscInt	lzs	=	zs,	lze	=	ze;
	PetscReal	***level;
	
	if (xs==0) lxs = xs+1;
	if (ys==0) lys = ys+1;
	if (zs==0) lzs = zs+1;

	if (xe==mx)	lxe	=	xe-1;
	if (ye==my)	lye	=	ye-1;
	if (ze==mz)	lze	=	ze-1;
	
	int	iter=0;
	Init_LevelSet_Vectors(user);
	Distance_Function_IC(user);
		
	Vec	D;
	double norm=100, norm_old;
		
	dtau = dx_min*0.25;
	//dtau = dx_min	*	0.5;
	
	VecDuplicate(LevelSet, &D);
	
	do {
		norm_old = norm;
		
		PetscPrintf(PETSC_COMM_WORLD,	"\nSolving Distance %d... (dtau=%f)\n",	iter, dtau);
		//Solve_Distance_Explicit(user);
		Solve_Distance(user, iter);
		VecWAXPY(D, -1., LevelSet_o, LevelSet);
		VecNorm(D, NORM_INFINITY, &norm);
		PetscPrintf(PETSC_COMM_WORLD, "\nNorm=%.5e\n\n", norm);
		
		PetscReal ***level;
		DAVecGetArray(user->da, LevelSet, &level);
		for	(k=zs; k<ze; k++)
		for	(j=ys; j<ye; j++)
		for	(i=xs; i<xe; i++)	if(level[k][j][i]<0) level[k][j][i]=0.01;
		DAVecRestoreArray(user->da, LevelSet, &level);
	
		if(iter > 10 && (fabs(norm)<1.e-5 || iter>1000) ) break;
		//if(iter>10 && iter%50==0) dtau *=1.04;
		VecCopy(LevelSet, LevelSet_o);
		
		iter++;
	}	while(1);
	VecDestroy(D);
	
	Vec	lLevelset;
	PetscReal	***llevel;
	VecDuplicate(user->lP, &lLevelset);

	DAGlobalToLocalBegin(user->da, LevelSet, INSERT_VALUES,	lLevelset);
	DAGlobalToLocalEnd(user->da, LevelSet, INSERT_VALUES,	lLevelset);

	DAVecGetArray(user->da,	LevelSet,	&level);
	DAVecGetArray(user->da,	lLevelset, &llevel);

	for	(k=zs; k<ze; k++)
	for	(j=ys; j<ye; j++)
	for	(i=xs; i<xe; i++)	{
		int	c=k, b=j,	a=i, flag=0;
		
		// Neumann conditions
		if(i==0) a=1,	flag=1;
		if(i==mx-1)	a=mx-2,	flag=1;
		if(j==0) b=1,	flag=1;
		if(j==my-1)	b=my-2,	flag=1;
		if(k==0) c=1,	flag=1;
		if(k==mz-1)	c=mz-2,	flag=1;
		
		if(i_periodic	&& i==0) a=mx-2, flag=1;
		else if(i_periodic &&	i==mx-1) a=1,	flag=1;
		
		if(j_periodic	&& j==0) b=my-2, flag=1;
		else if(j_periodic &&	j==my-1) b=1,	flag=1;
		
		if(k_periodic	&& k==0) c=mz-2, flag=1;
		else if(k_periodic &&	k==mz-1) c=1,	flag=1;
		
		
		if(ii_periodic &&	i==0)	a=-2,	flag=1;
		else if(ii_periodic	&& i==mx-1)	a=mx+1,	flag=1;
		
		if(jj_periodic &&	j==0)	b=-2,	flag=1;
		else if(jj_periodic	&& j==my-1)	b=my+1,	flag=1;
		
		if(kk_periodic &&	k==0)	c=-2,	flag=1;
		else if(kk_periodic	&& k==mz-1)	c=mz+1,	flag=1;
		
		if(flag) level[k][j][i]	=	llevel[c][b][a];
	}
	DAVecRestoreArray(user->da,	LevelSet,	&level);
	DAVecRestoreArray(user->da,	lLevelset, &llevel);

	VecDestroy(lLevelset);
	VecCopy(LevelSet,	user->Distance);	
	Destroy_LevelSet_Vectors(user);
};
Exemple #16
0
/* 
   FormResidual - Evaluates nonlinear function, F(x).

   Input Parameters:
.  ot - the OT context
.  X - input vector
.  ptr - optional user-defined context, as set by OTSetFunction()

   Output Parameter:
.  F - function vector
 */
int FormResidual(TAO_SOLVER ot,Vec X,Vec F,void *ptr)
{
  AppCtx  *user = (AppCtx *) ptr;
  int     info, i, j, row, mx, my, xs, ys, xm, ym, gxs, gys, gxm, gym;
  double  two = 2.0, one = 1.0, lambda,hx, hy, hxdhy, hydhx,sc;
  PetscScalar  u, uxx, uyy, *x,*f;
  Vec localX=user->localX,localF=user->localF;

  mx = user->mx;            my = user->my;            lambda = user->param;
  hx = one/(double)(mx-1);  hy = one/(double)(my-1);
  sc = hx*hy*lambda;        hxdhy = hx/hy;            hydhx = hy/hx;

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

  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 = VecGetArray(localX,&x); CHKERRQ(info);
  info = VecGetArray(localF,&f); CHKERRQ(info);

  /*
     Get local grid 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);

  /*
     Compute function over the locally owned part of the grid
  */
  for (j=ys; j<ys+ym; j++) {
    row = (j - gys)*gxm + xs - gxs - 1; 
    for (i=xs; i<xs+xm; i++) {
      row++;
      if (i == 0 || j == 0 || i == mx-1 || j == my-1 ) {
        f[row] = x[row];
        continue;
      }
      u = x[row];
      uxx = (two*u - x[row-1] - x[row+1])*hydhx;
      uyy = (two*u - x[row-gxm] - x[row+gxm])*hxdhy;
      f[row] = uxx + uyy - sc*exp(u);
    }
  }

  /*
     Restore vectors
  */
  info = VecRestoreArray(localX,&x); CHKERRQ(info);
  info = VecRestoreArray(localF,&f); CHKERRQ(info);

  /*
     Insert values into global vector
  */
  info = DALocalToGlobal(user->da,localF,INSERT_VALUES,F); CHKERRQ(info);
  PetscLogFlops(11*ym*xm);
  return 0; 
} 
Exemple #17
0
void Distance_Function_RHS (UserCtx *user, Vec Levelset_RHS, int wall_distance)
{
	DA		da = user->da, fda = user->fda;
	DALocalInfo	info = user->info;
	PetscInt	xs,	xe,	ys,	ye,	zs,	ze;
	PetscInt	mx,	my,	mz;
	PetscInt	i, j,	k;
	PetscReal	dpdc,	dpde,	dpdz;
	
	Vec		Csi	=	user->lCsi,	Eta	=	user->lEta,	Zet	=	user->lZet;
	Vec		Aj	=	user->lAj;

	Cmpnts	***csi,	***eta,	***zet;
	PetscReal	***aj, ***level, ***level0,	***rhs,	***grad_level;

	PetscInt	lxs, lys,	lzs, lxe,	lye, lze;
	PetscReal	***nvert;
	
	Vec	L, lLevelset0;	// grad	level, level0
	
	xs = info.xs;	xe = xs	+	info.xm;
	ys = info.ys;	ye = ys	+	info.ym;
	zs = info.zs;	ze = zs	+	info.zm;
	
	lxs	=	xs;	lxe	=	xe;
	lys	=	ys;	lye	=	ye;
	lzs	=	zs;	lze	=	ze;
	
	mx = info.mx;	my = info.my;	mz = info.mz;
	
	if (xs==0) lxs = xs+1;
	if (ys==0) lys = ys+1;
	if (zs==0) lzs = zs+1;

	if (xe==mx)	lxe	=	xe-1;
	if (ye==my)	lye	=	ye-1;
	if (ze==mz)	lze	=	ze-1;
	
	VecSet(Levelset_RHS, 0);
	
	VecDuplicate(user->lP, &L);
	VecDuplicate(user->lP, &lLevelset0);
	
	DAGlobalToLocalBegin(user->da, LevelSet0, INSERT_VALUES, lLevelset0);
	DAGlobalToLocalEnd(user->da, LevelSet0,	INSERT_VALUES, lLevelset0);
	
	DAVecGetArray(fda, Csi,	&csi);
	DAVecGetArray(fda, Eta,	&eta);
	DAVecGetArray(fda, Zet,	&zet);
	DAVecGetArray(da,	 Aj,	&aj);
	DAVecGetArray(da,	user->lNvert,	&nvert);
	DAVecGetArray(da,	user->lLevelset, &level);
	DAVecGetArray(da,	lLevelset0,	&level0);
	DAVecGetArray(da,	Levelset_RHS,	&rhs);
	
	DAVecGetArray(da,  L,  &grad_level);
	for	(k=lzs;	k<lze; k++)
	for	(j=lys;	j<lye; j++)
	for	(i=lxs;	i<lxe; i++) {
		double dldc, dlde, dldz;
		double dl_dx, dl_dy, dl_dz;
		
		double csi0=csi[k][j][i].x,csi1=csi[k][j][i].y, csi2=csi[k][j][i].z;
		double eta0=eta[k][j][i].x,eta1=eta[k][j][i].y, eta2=eta[k][j][i].z;
		double zet0=zet[k][j][i].x,zet1=zet[k][j][i].y, zet2=zet[k][j][i].z;
		double ajc = aj[k][j][i];
		
		double dx=pow(1./aj[k][j][i],1./3.);
		if(dthick_set) dx = dthick;

		double sgn = sign1(level0[k][j][i], dx);
		//if(wall_distance)	sgn	=	sign(level0[k][j][i]);
		
		//Compute_dlevel_center_levelset (i, j, k, mx, my, mz, sgn, wall_distance, level, nvert, &dldc, &dlde, &dldz);
		Compute_dlevel_center_levelset (i, j, k, mx, my, mz, sign(level0[k][j][i]), wall_distance, level, nvert, &dldc, &dlde, &dldz); //100521
		
		Compute_dscalar_dxyz (csi0, csi1, csi2, eta0, eta1, eta2, zet0, zet1, zet2, ajc, dldc, dlde, dldz, &dl_dx, &dl_dy, &dl_dz);
		
		grad_level[k][j][i] = sqrt( dl_dx*dl_dx	+ dl_dy*dl_dy +	dl_dz*dl_dz );
		if(nvert[k][j][i]>0.1) grad_level[k][j][i]=0;
	}
	DAVecRestoreArray(da,  L,  &grad_level);

	DALocalToLocalBegin(user->da, L, INSERT_VALUES,	L);
	DALocalToLocalEnd(user->da, L, INSERT_VALUES, L);
	
	DAVecGetArray(da,  L,  &grad_level);
	
	// Neumann,	periodic conditions
	if(xs==0 ||	xe==mx)	{
		int	from,	to;
		for	(k=lzs;	k<lze; k++)
		for	(j=lys;	j<lye; j++)	{
			if(xs==0)	{
				i	=	1, from	=	i, to	=	0;
				
				if(i_periodic) from	=	mx-2;
				else if(ii_periodic) from	=	-2;
				
				grad_level[k][j][to] = grad_level[k][j][from];
			}
			
			if(xe==mx) {
				i	=	mx-2,	from = i,	to = mx-1;
				
				if(i_periodic) from	=	1;
				else if(ii_periodic) from	=	mx+1;
				
				grad_level[k][j][to] = grad_level[k][j][from];
			}
		}
	}
	
	if(ys==0 ||	ye==my)	{
		int	from,	to;
				
		for	(k=lzs;	k<lze; k++)
		for	(i=lxs;	i<lxe; i++)	{
			if(ys==0)	{
				j	=	1, from	=	j, to	=	0;
				
				if(j_periodic) from	=	my-2;
				else if(jj_periodic) from	=	-2;
				
				grad_level[k][to][i] = grad_level[k][from][i];
			}
			
			if(ye==my) {
				j	=	my-2,	from = j,	to = my-1;
				
				if(j_periodic) from	=	1;
				else if(jj_periodic) from	=	my+1;
				
				grad_level[k][to][i] = grad_level[k][from][i];
			}
		}
	}
	
	if(zs==0 ||	ze==mz)	{
		int	from,	to;
		
		for	(j=lys;	j<lye; j++)
		for	(i=lxs;	i<lxe; i++)	{
			if(zs==0)	{
				k	=	1, from	=	k, to	=	0;
				
				if(k_periodic) from	=	mz-2;
				else if(kk_periodic) from	=	-2;
				
				grad_level[to][j][i] = grad_level[from][j][i];
			}
			
			if(ze==mz) {
				k	=	mz-2,	from = k,	to = mz-1;
				
				if(k_periodic) from	=	1;
				else if(kk_periodic) from	=	mz+1;
				
				grad_level[to][j][i] = grad_level[from][j][i];
			}
		}
	}
	
	DAVecRestoreArray(da,  L,  &grad_level);
	DALocalToLocalBegin(user->da, L, INSERT_VALUES,	L);
	DALocalToLocalEnd(user->da, L, INSERT_VALUES, L);
	DAVecGetArray(da,  L,  &grad_level);

	for(k=zs; k<ze; k++)
	for(j=ys; j<ye; j++)
	for(i=xs; i<xe; i++)	{
		if (i<= 0 || i>= mx-1 || j<=0 || j>=my-1 || k<=0 || k>=mz-1 || nvert[k][j][i]>1.1){
			rhs[k][j][i]=0.;
			continue;
		}
		
		if(nvert[k][j][i]>0.1) {
		  rhs[k][j][i]=0.;
		  continue;
		}
		
		if(wall_distance) {
			if(nvert[k][j][i]>0.1) { rhs[k][j][i]=0.; continue; }
			if(i <= 1 && (user->bctype[0]==1 || user->bctype[0]==-1 || user->bctype[0]==-2)) { rhs[k][j][i]=0.; continue; }
			if(i >=	mx-2 &&	(user->bctype[1]==1 || user->bctype[1]==-1 || user->bctype[1]==-2)) { rhs[k][j][i]=0.; continue; }
			if(j <=1 && (user->bctype[2]==1 || user->bctype[2]==-1 || user->bctype[2]==-2)) { rhs[k][j][i]=0.; continue; }
			if(j >=my-2 && (user->bctype[3]==1 || user->bctype[3]==-1 || user->bctype[3]==-2 || user->bctype[3]==12)) { rhs[k][j][i]=0.; continue; }
			if(k<=1	&& (user->bctype[4]==1 || user->bctype[4]==-1 || user->bctype[4]==-2)) { rhs[k][j][i]=0.; continue; }
			if(k>=mz-2 && (user->bctype[5]==1 || user->bctype[5]==-1 || user->bctype[5]==-2)){ rhs[k][j][i]=0.; continue; }
		}		
		else if( !wall_distance	&& user->bctype[4]==5 && user->bctype[5]==4) {
		  //if ( fix_inlet && k==1 ) { rhs[k][j][i] = 0; continue; }
		  //haha if ( fix_outlet && k==mz-2 ) { rhs[k][j][i] = 0; continue; } // important to stabilize outlet
		}
		
		double dx=pow(1./aj[k][j][i],1./3.);
		if(dthick_set) dx = dthick;
		double sgn = sign1(level0[k][j][i],dx);
		//if(wall_distance)	sgn	=	sign(level0[k][j][i]);
		
		double denom[3][3][3], num[3][3][3], weight[3][3][3];
		
		for(int	p=-1;	p<=1;	p++)
		for(int	q=-1;	q<=1;	q++)
		for(int	r=-1;	r<=1;	r++) {
			int	R=r+1, Q=q+1,	P=p+1;
			int	K=k+r, J=j+q,	I=i+p;
			double phi = level[K][J][I], grad	=	grad_level[K][J][I], dx=pow(1./aj[K][J][I],1./3.);
			if(dthick_set) dx	=	dthick;

			double f = dH(phi,dx)	*	grad;
			
			double _sgn	=	sign1( level0[K][J][I],	dx );
			//if(wall_distance)	_sgn = sign(level0[K][J][I]);
			
			num[R][Q][P] = dH(phi,dx) * _sgn * ( 1.	- grad );
			denom[R][Q][P] = dH(phi,dx) * f;
		}
		
		for(int	p=-1;	p<=1;	p++)
		for(int	q=-1;	q<=1;	q++)
		for(int	r=-1;	r<=1;	r++) {
		  int	R=r+1, Q=q+1,	P=p+1;
		  int	K=k+r, J=j+q,	I=i+p;
		  if( (!i_periodic && !ii_periodic && (I==0 || I==mx-1 ) ) ||
			(!j_periodic && !jj_periodic && (J==0 || J==my-1 ) ) || 
			(!k_periodic && !kk_periodic && (K==0 || K==mz-1) ) ||	
			nvert[K][J][I]>0.1) {
		    num[R][Q][P] = num[1][1][1];
		    denom[R][Q][P] = denom[1][1][1];
		  }
		}
		
		get_weight (i, j, k, mx, my, mz, aj, nvert, 0.1, weight);
		
		double numerator = integrate_testfilter(num, weight);
		double denominator = integrate_testfilter(denom, weight);
		
		double correction;
		
		if(	fabs(denominator)<1.e-10 ) correction=0;
		else {
			double grad	=	grad_level[k][j][i];
			double phi = level[k][j][i];
			double dx=pow(1./aj[k][j][i],1./3.);
			if(dthick_set) dx	=	dthick;

			double f = dH(phi,dx)	*	grad;
			correction = - numerator / denominator;
			correction *=	dH(phi,dx) * grad;
		}
		
		double dlevel_dx, dlevel_dy, dlevel_dz;
		double dldc, dlde, dldz;
		double csi0 = csi[k][j][i].x, csi1 = csi[k][j][i].y, csi2 = csi[k][j][i].z;
		double eta0 = eta[k][j][i].x, eta1 = eta[k][j][i].y, eta2 = eta[k][j][i].z;
		double zet0 = zet[k][j][i].x, zet1 = zet[k][j][i].y, zet2 = zet[k][j][i].z;
		double ajc = aj[k][j][i];
		
		//Compute_dlevel_center_levelset (i, j, k, mx, my, mz, sgn, wall_distance, level, nvert, &dldc, &dlde, &dldz);
		Compute_dlevel_center_levelset (i, j, k, mx, my, mz, sign(level0[k][j][i]), wall_distance, level, nvert, &dldc, &dlde, &dldz); //100521

		Compute_dscalar_dxyz (csi0, csi1, csi2,	eta0, eta1, eta2, zet0,	zet1, zet2, ajc, dldc, dlde, dldz, &dlevel_dx, &dlevel_dy, &dlevel_dz);
		rhs[k][j][i] = sgn * ( 1. - sqrt( dlevel_dx*dlevel_dx +	dlevel_dy*dlevel_dy + dlevel_dz*dlevel_dz ) );
			
		if(nvert[k][j][i+1]+nvert[k][j][i-1]+nvert[k][j+1][i]+nvert[k][j-1][i]+nvert[k+1][j][i]+nvert[k-1][j][i]>0.1) {
		  // correction = 0;
		}

		if(!wall_distance) rhs[k][j][i] += correction;	// Sussman Fetami
	}

	DAVecRestoreArray(da,	 L,	 &grad_level);
	DAVecRestoreArray(fda, Csi,	&csi);
	DAVecRestoreArray(fda, Eta,	&eta);
	DAVecRestoreArray(fda, Zet,	&zet);
	DAVecRestoreArray(da,	 Aj,	&aj);
	DAVecRestoreArray(da,	user->lNvert,	&nvert);
	DAVecRestoreArray(da,	user->lLevelset, &level);
	DAVecRestoreArray(da,	lLevelset0,	&level0);
	DAVecRestoreArray(da,	Levelset_RHS,	&rhs);
	
	VecDestroy(L);
	VecDestroy(lLevelset0);
}
Exemple #18
0
/*
   Here is my custom preconditioner

    Capital vectors: X, X1 are global vectors
    Small vectors: x, x1 are local ghosted vectors
    Prefixed a: ax1, aY1 are arrays that access the vector values (either local (ax1) or global aY1)

 */
PetscErrorCode MyPCApply(PC pc,Vec X,Vec Y)
{
    AppCtx         *app;
    PetscErrorCode ierr;
    Vec            X1,X2,X3,x1,x2,Y1,Y2,Y3;
    DALocalInfo    info1,info2,info3;
    DA             da1,da2,da3;
    PetscInt       i,j;
    FluidField     *ax1,*aY1;
    PetscScalar    **ax2,**aY2;

    PetscFunctionBegin;
    ierr = PCShellGetContext(pc,(void**)&app);
    CHKERRQ(ierr);
    /* obtain information about the three meshes */
    ierr = DMCompositeGetEntries(app->pack,&da1,&da2,&da3);
    CHKERRQ(ierr);
    ierr = DAGetLocalInfo(da1,&info1);
    CHKERRQ(ierr);
    ierr = DAGetLocalInfo(da2,&info2);
    CHKERRQ(ierr);
    ierr = DAGetLocalInfo(da3,&info3);
    CHKERRQ(ierr);

    /* get ghosted version of fluid and thermal conduction, global for phi and C */
    ierr = DMCompositeGetAccess(app->pack,X,&X1,&X2,&X3);
    CHKERRQ(ierr);
    ierr = DMCompositeGetLocalVectors(app->pack,&x1,&x2,PETSC_NULL);
    CHKERRQ(ierr);
    ierr = DAGlobalToLocalBegin(da1,X1,INSERT_VALUES,x1);
    CHKERRQ(ierr);
    ierr = DAGlobalToLocalEnd(da1,X1,INSERT_VALUES,x1);
    CHKERRQ(ierr);
    ierr = DAGlobalToLocalBegin(da2,X2,INSERT_VALUES,x2);
    CHKERRQ(ierr);
    ierr = DAGlobalToLocalEnd(da2,X2,INSERT_VALUES,x2);
    CHKERRQ(ierr);

    /* get global version of result vector */
    ierr = DMCompositeGetAccess(app->pack,Y,&Y1,&Y2,&Y3);
    CHKERRQ(ierr);

    /* pull out the phi and C values */
    ierr = VecStrideGather(X3,0,app->dx,INSERT_VALUES);
    CHKERRQ(ierr);
    ierr = VecStrideGather(X3,1,app->c,INSERT_VALUES);
    CHKERRQ(ierr);

    /* update C via formula 38; put back into return vector */
    ierr = VecAXPY(app->c,0.0,app->dx);
    CHKERRQ(ierr);
    ierr = VecScale(app->c,1.0);
    CHKERRQ(ierr);
    ierr = VecStrideScatter(app->c,1,Y3,INSERT_VALUES);
    CHKERRQ(ierr);

    /* form the right hand side of the phi equation; solve system; put back into return vector */
    ierr = VecAXPBY(app->dx,0.0,1.0,app->c);
    CHKERRQ(ierr);
    ierr = DMMGSolve(app->fdmmg);
    CHKERRQ(ierr);
    ierr = VecStrideScatter(app->dy,0,Y3,INSERT_VALUES);
    CHKERRQ(ierr);

    /* access the ghosted x1 and x2 as arrays */
    ierr = DAVecGetArray(da1,x1,&ax1);
    CHKERRQ(ierr);
    ierr = DAVecGetArray(da2,x2,&ax2);
    CHKERRQ(ierr);

    /* access global y1 and y2 as arrays */
    ierr = DAVecGetArray(da1,Y1,&aY1);
    CHKERRQ(ierr);
    ierr = DAVecGetArray(da2,Y2,&aY2);
    CHKERRQ(ierr);

    for (i=info1.xs; i<info1.xs+info1.xm; i++) {
        aY1[i].prss = ax1[i].prss;
        aY1[i].ergg = ax1[i].ergg;
        aY1[i].ergf = ax1[i].ergf;
        aY1[i].alfg = ax1[i].alfg;
        aY1[i].velg = ax1[i].velg;
        aY1[i].velf = ax1[i].velf;
    }

    for (j=info2.ys; j<info2.ys+info2.ym; j++) {
        for (i=info2.xs; i<info2.xs+info2.xm; i++) {
            aY2[j][i] = ax2[j][i];
        }
    }

    ierr = DAVecRestoreArray(da1,x1,&ax1);
    CHKERRQ(ierr);
    ierr = DAVecRestoreArray(da2,x2,&ax2);
    CHKERRQ(ierr);
    ierr = DAVecRestoreArray(da1,Y1,&aY1);
    CHKERRQ(ierr);
    ierr = DAVecRestoreArray(da2,Y2,&aY2);
    CHKERRQ(ierr);

    ierr = DMCompositeRestoreLocalVectors(app->pack,&x1,&x2,PETSC_NULL);
    CHKERRQ(ierr);
    ierr = DMCompositeRestoreAccess(app->pack,X,&X1,&X2,&X3);
    CHKERRQ(ierr);
    ierr = DMCompositeRestoreAccess(app->pack,Y,&Y1,&Y2,&Y3);
    CHKERRQ(ierr);

    PetscFunctionReturn(0);
}
Exemple #19
0
static int TaoDA2dLoopADFunctionGradient(TAO_APPLICATION tao, DA da, Vec X, double *f, Vec G, void * ctx) {

  TaoDA2D1DOFADICFGCtx *myapp = (TaoDA2D1DOFADICFGCtx*) ctx;
  MPI_Comm comm;
  Vec localX, localG;
  int info, i, j, coor[2];
  int xs, xm, gxs, gxm, xe, ys, ym, gys, gym, ye;
  PetscScalar **x, **g;
  PetscScalar floc = 0.0;
  PetscScalar zero = 0.0;
  DERIV_TYPE adF,*adX=myapp->adX;

  info = DAGetLocalVector(da, &localX); CHKERRQ(info);
  info = DAGetLocalVector(da, &localG); CHKERRQ(info);
  info = VecSet(G, zero); CHKERRQ(info);
  info = VecSet(localG, zero); CHKERRQ(info);

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

  info = DAVecGetArray(da, localX, (void**)&x); CHKERRQ(info);
  info = DAVecGetArray(da, localG, (void**)&g); CHKERRQ(info);

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

  xe = gxs + gxm - 1;
  ye = gys + gym - 1;

  for (j = ys; j < ye; j++) {
    for (i = xs; i < xe; i++) {

        DERIV_val(adX[0]) = x[j][i];
        DERIV_val(adX[1]) = x[j][i+1];
        DERIV_val(adX[2]) = x[j+1][i];
        DERIV_val(adX[3]) = x[j+1][i+1];
        coor[0] = i; coor[1] = j;

        info = myapp->computeadicfunctiongradient(coor,adX,&adF,myapp->elementfgctx);
	CHKERRQ(info);

        floc += DERIV_val(adF);

        g[j][i] += DERIV_grad(adF)[0];
        g[j][i+1] += DERIV_grad(adF)[1];
        g[j+1][i] += DERIV_grad(adF)[2];
        g[j+1][i+1] += DERIV_grad(adF)[3];
    }
  }

  PetscLogFlops((ye-ys)*(xe-xs)*(myapp->elementfgflops + 5));

  PetscObjectGetComm((PetscObject)da,&comm); CHKERRQ(info);
  info = MPI_Allreduce(&floc, f, 1, MPI_DOUBLE, MPI_SUM, comm); CHKERRQ(info);

  info = DAVecRestoreArray(da, localX, (void**)&x); CHKERRQ(info);
  info = DAVecRestoreArray(da, localG, (void**)&g); CHKERRQ(info);

  info = DALocalToGlobalBegin(da, localG, G); CHKERRQ(info);
  info = DALocalToGlobalEnd(da, localG, G); CHKERRQ(info);

  info = DARestoreLocalVector(da, &localX); CHKERRQ(info);
  info = DARestoreLocalVector(da, &localG); CHKERRQ(info);

  PetscFunctionReturn(0);
} /* TaoDA2dLoopADFunctionGradient */
Exemple #20
0
/*
  WholeMSurfHessian - Evaluates Hessian over the whole grid

  Input:
    daapplication - TAO application object
    da  - distributed array
    X   - the current point, at which the function and gradient are evaluated
    ptr - user-defined application context

  Output:
    H - Hessian at X
*/
static int WholeMSurfHessian(TAO_APPLICATION daapplication, DA da, Vec X, Mat H, void *ptr) {

  AppCtx *user = (AppCtx*)ptr;
  Vec localX;
  int info;
  PetscInt  i, j, ind[4];
  PetscInt xs, xm, gxs, gxm, xe, ys, ym, gys, gym, ye;
  double smallH[4][4];
  double **x;

  double hx, hy, area, byhxhx, byhyhy;
  double dvdx, dvdy, flow, fup;
  double areadivf, areadivf3;
  PetscTruth assembled;

  hx = user->hx;
  hy = user->hy;
  area = user->area;
  
  byhxhx = 1.0 / (hx * hx);
  byhyhy = 1.0 / (hy * hy);

  info = DAGetLocalVector(da, &localX); CHKERRQ(info);
  info = MatAssembled(H,&assembled); CHKERRQ(info);
  if (assembled){info = MatZeroEntries(H);  CHKERRQ(info);}

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

  info = DAVecGetArray(da, localX, (void**)&x); CHKERRQ(info);

  info = DAGetCorners(da, &xs, &ys, TAO_NULL, &xm, &ym, TAO_NULL); CHKERRQ(info);
  info = DAGetGhostCorners(da, &gxs, &gys, TAO_NULL, &gxm, &gym, TAO_NULL); CHKERRQ(info);

  xe = gxs + gxm - 1;
  ye = gys + gym - 1;
  for (j = ys; j < ye; j++) {
    for (i = xs; i < xe; i++) {

      /* 0 is 0,0; 1 is 1,0; 2 is 0,1; 3 is 1,1 */
      dvdx = (x[j][i] - x[j][i+1]) / hx;  /* lower triangle contribution */
      dvdy = (x[j][i] - x[j+1][i]) / hy;
      flow = sqrt( 1 + dvdx * dvdx + dvdy * dvdy );
      dvdx = dvdx / hx;
      dvdy = dvdy / hy;
      areadivf = area / flow;
      areadivf3 = areadivf / (flow * flow);
      smallH[0][0] = areadivf * (byhxhx + byhyhy) - areadivf3 * (dvdx + dvdy) * (dvdx + dvdy);
      smallH[0][1] = areadivf * (-byhxhx) + areadivf3 * (dvdx + dvdy) * (dvdx);
      smallH[0][2] = areadivf * (-byhyhy) + areadivf3 * (dvdx + dvdy) * (dvdy);
      smallH[0][3] = 0.0;
      smallH[1][1] = areadivf * byhxhx - areadivf3 * dvdx * dvdx;
      smallH[1][2] = areadivf3 * (-dvdx) * dvdy;
      smallH[2][2] = areadivf * byhyhy - areadivf3 * dvdy * dvdy;

      /* upper triangle contribution */
      dvdx = (x[j+1][i+1] - x[j+1][i]) / hx;
      dvdy = (x[j+1][i+1] - x[j][i+1]) / hy;
      fup = sqrt( 1 + dvdx * dvdx + dvdy * dvdy );
      dvdx = dvdx / hx;
      dvdy = dvdy / hy;
      areadivf = area / fup;
      areadivf3 = areadivf / (fup * fup);
      smallH[1][1] += areadivf * byhyhy - areadivf3 * dvdy * dvdy;
      smallH[1][2] += areadivf3 * (-dvdy) * dvdx;
      smallH[2][2] += areadivf * byhxhx - areadivf3 * (dvdx * dvdx);
      smallH[1][3] = areadivf * (-byhyhy) + areadivf3 * (dvdx + dvdy) * dvdy;
      smallH[2][3] = areadivf * (-byhxhx) + areadivf3 * (dvdx + dvdy) * dvdx;
      smallH[3][3] = areadivf * (byhxhx + byhyhy) - areadivf3 * (dvdx + dvdy) * (dvdx + dvdy);

      smallH[1][0] = smallH[0][1];
      smallH[2][0] = smallH[0][2];
      smallH[3][0] = smallH[0][3];
      smallH[2][1] = smallH[1][2];
      smallH[3][1] = smallH[1][3];
      smallH[3][2] = smallH[2][3];

      ind[0] = (j-gys) * gxm + (i-gxs);
      ind[1] = ind[0] + 1;
      ind[2] = ind[0] + gxm;
      ind[3] = ind[2] + 1;
      info = MatSetValuesLocal(H,4,ind,4,ind,(PetscScalar*)smallH,ADD_VALUES); CHKERRQ(info);

    }
  }

  info = DAVecRestoreArray(da, localX, (void**)&x); CHKERRQ(info);

  info = MatAssemblyBegin(H, MAT_FINAL_ASSEMBLY); CHKERRQ(info);
  info = MatAssemblyEnd(H, MAT_FINAL_ASSEMBLY); CHKERRQ(info);
  info = MatSetOption(H, MAT_SYMMETRIC, PETSC_TRUE); CHKERRQ(info);

  info = DARestoreLocalVector(da, &localX); CHKERRQ(info);

  info = PetscLogFlops((xe-xs) * (ye-ys) * 83 + 4); CHKERRQ(info);
  return 0;

} /* WholeMSurfHessian */
Exemple #21
0
int main(int argc,char **argv)
{
  PetscMPIInt    size,rank;
  PetscInt       M=8,dof=1,stencil_width=1,i,start,end,P=5,N = 6,m=PETSC_DECIDE,n=PETSC_DECIDE,p=PETSC_DECIDE,pt = 0,st = 0;
  PetscErrorCode ierr;
  PetscTruth     flg2,flg3,flg;
  DAPeriodicType periodic = DA_NONPERIODIC;
  DAStencilType  stencil_type = DA_STENCIL_STAR;
  DA             da;
  SDA            sda;
  Vec            local,global,local_copy;
  PetscScalar    value,*in,*out;
  PetscReal      norm,work;
  PetscViewer    viewer;
  char           filename[PETSC_MAX_PATH_LEN];
  FILE           *file;


  ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); 

  ierr = PetscOptionsGetInt(PETSC_NULL,"-M",&M,PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscOptionsGetInt(PETSC_NULL,"-N",&N,PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscOptionsGetInt(PETSC_NULL,"-P",&P,PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscOptionsGetInt(PETSC_NULL,"-dof",&dof,PETSC_NULL);CHKERRQ(ierr); 
  ierr = PetscOptionsGetInt(PETSC_NULL,"-stencil_width",&stencil_width,PETSC_NULL);CHKERRQ(ierr); 
  ierr = PetscOptionsGetInt(PETSC_NULL,"-periodic",&pt,PETSC_NULL);CHKERRQ(ierr); 
  periodic = (DAPeriodicType) pt;
  ierr = PetscOptionsGetInt(PETSC_NULL,"-stencil_type",&st,PETSC_NULL);CHKERRQ(ierr); 
  stencil_type = (DAStencilType) st;

  ierr = PetscOptionsHasName(PETSC_NULL,"-1d",&flg2);CHKERRQ(ierr);
  ierr = PetscOptionsHasName(PETSC_NULL,"-2d",&flg2);CHKERRQ(ierr);
  ierr = PetscOptionsHasName(PETSC_NULL,"-3d",&flg3);CHKERRQ(ierr);
  if (flg2) {
    ierr = DACreate2d(PETSC_COMM_WORLD,periodic,stencil_type,M,N,m,n,dof,stencil_width,0,0,&da);CHKERRQ(ierr);
    ierr = SDACreate2d(PETSC_COMM_WORLD,periodic,stencil_type,M,N,m,n,dof,stencil_width,0,0,&sda);CHKERRQ(ierr);
  } else if (flg3) {
    ierr = DACreate3d(PETSC_COMM_WORLD,periodic,stencil_type,M,N,P,m,n,p,dof,stencil_width,0,0,0,&da);CHKERRQ(ierr);
    ierr = SDACreate3d(PETSC_COMM_WORLD,periodic,stencil_type,M,N,P,m,n,p,dof,stencil_width,0,0,0,&sda);CHKERRQ(ierr);
  }
  else {
    ierr = DACreate1d(PETSC_COMM_WORLD,periodic,M,dof,stencil_width,PETSC_NULL,&da);CHKERRQ(ierr);
    ierr = SDACreate1d(PETSC_COMM_WORLD,periodic,M,dof,stencil_width,PETSC_NULL,&sda);CHKERRQ(ierr);
  }

  ierr = DACreateGlobalVector(da,&global);CHKERRQ(ierr);
  ierr = DACreateLocalVector(da,&local);CHKERRQ(ierr);
  ierr = VecDuplicate(local,&local_copy);CHKERRQ(ierr);
  
  /* zero out vectors so that ghostpoints are zero */
  value = 0;
  ierr = VecSet(local,value);CHKERRQ(ierr);
  ierr = VecSet(local_copy,value);CHKERRQ(ierr);

  ierr = VecGetOwnershipRange(global,&start,&end);CHKERRQ(ierr);
  for (i=start; i<end; i++) {
    value = i + 1;
    ierr = VecSetValues(global,1,&i,&value,INSERT_VALUES);CHKERRQ(ierr);
  }
  ierr = VecAssemblyBegin(global);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(global);CHKERRQ(ierr);

  ierr = DAGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
  ierr = DAGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr);

  flg  = PETSC_FALSE;
  ierr = PetscOptionsGetTruth(PETSC_NULL,"-same_array",&flg,PETSC_NULL);CHKERRQ(ierr);
  if (flg) {
    /* test the case where the input and output array is the same */
    ierr = VecCopy(local,local_copy);CHKERRQ(ierr);
    ierr = VecGetArray(local_copy,&in);CHKERRQ(ierr);
    ierr = VecRestoreArray(local_copy,PETSC_NULL);CHKERRQ(ierr);
    ierr = SDALocalToLocalBegin(sda,in,INSERT_VALUES,in);CHKERRQ(ierr);
    ierr = SDALocalToLocalEnd(sda,in,INSERT_VALUES,in);CHKERRQ(ierr);
  } else {
    ierr = VecGetArray(local,&out);CHKERRQ(ierr);
    ierr = VecRestoreArray(local,PETSC_NULL);CHKERRQ(ierr);
    ierr = VecGetArray(local_copy,&in);CHKERRQ(ierr);
    ierr = VecRestoreArray(local_copy,PETSC_NULL);CHKERRQ(ierr);
    ierr = SDALocalToLocalBegin(sda,out,INSERT_VALUES,in);CHKERRQ(ierr);
    ierr = SDALocalToLocalEnd(sda,out,INSERT_VALUES,in);CHKERRQ(ierr);
  }

  flg  = PETSC_FALSE;
  ierr = PetscOptionsGetTruth(PETSC_NULL,"-save",&flg,PETSC_NULL);CHKERRQ(ierr);
  if (flg) {
    ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
    sprintf(filename,"local.%d",rank);
    ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr);
    ierr = PetscViewerASCIIGetPointer(viewer,&file);CHKERRQ(ierr);
    ierr = VecView(local,viewer);CHKERRQ(ierr);
    fprintf(file,"Vector with correct ghost points\n");
    ierr = VecView(local_copy,viewer);CHKERRQ(ierr);
    ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
  }

  ierr = VecAXPY(local_copy,-1.0,local);CHKERRQ(ierr);
  ierr = VecNorm(local_copy,NORM_MAX,&work);CHKERRQ(ierr);
  ierr = MPI_Allreduce(&work,&norm,1,MPIU_REAL,MPI_MAX,PETSC_COMM_WORLD);CHKERRQ(ierr);
  if (norm != 0.0) {
    ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of difference %G should be zero\n",norm);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Number of processors %d\n",size);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  M,N,P,dof %D %D %D %D\n",M,N,P,dof);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  stencil_width %D stencil_type %d periodic %d\n",stencil_width,(int)stencil_type,(int)periodic);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  dimension %d\n",1 + (int) flg2 + (int) flg3);CHKERRQ(ierr);
  }
   
  ierr = DADestroy(da);CHKERRQ(ierr);
  ierr = SDADestroy(sda);CHKERRQ(ierr);
  ierr = VecDestroy(local_copy);CHKERRQ(ierr);
  ierr = VecDestroy(local);CHKERRQ(ierr);
  ierr = VecDestroy(global);CHKERRQ(ierr);
  ierr = PetscFinalize();CHKERRQ(ierr);
  return 0;
}
Exemple #22
0
int main(int argc,char **argv)
{
  PetscInt       M = 13,dof=1,s=1,wrap=0,i,n,j;
  PetscErrorCode ierr;
  DA             da;
  PetscViewer    viewer;
  Vec            local,locala,global,coors;
  PetscScalar    *x,*alocal;
  PetscDraw      draw;
  char           fname[16];

  ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); 

  /* Create viewers */
  ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",PETSC_DECIDE,PETSC_DECIDE,600,200,&viewer);CHKERRQ(ierr);
  ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
  ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr);

  /* Read options */
  ierr = PetscOptionsGetInt(PETSC_NULL,"-M",&M,PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscOptionsGetInt(PETSC_NULL,"-dof",&dof,PETSC_NULL);CHKERRQ(ierr); 
  ierr = PetscOptionsGetInt(PETSC_NULL,"-s",&s,PETSC_NULL);CHKERRQ(ierr); 
  ierr = PetscOptionsGetInt(PETSC_NULL,"-periodic",&wrap,PETSC_NULL);CHKERRQ(ierr); 

  /* Create distributed array and get vectors */
  ierr = DACreate1d(PETSC_COMM_WORLD,(DAPeriodicType)wrap,M,dof,s,PETSC_NULL,&da);CHKERRQ(ierr);
  ierr = DASetUniformCoordinates(da,0.0,1.0,0.0,0.0,0.0,0.0);CHKERRQ(ierr);
  for (i=0; i<dof; i++) {
    sprintf(fname,"Field %d",(int)i);
    ierr = DASetFieldName(da,i,fname);
  }

  ierr = DAView(da,viewer);CHKERRQ(ierr);
  ierr = DACreateGlobalVector(da,&global);CHKERRQ(ierr);
  ierr = DACreateLocalVector(da,&local);CHKERRQ(ierr);
  ierr = DACreateLocalVector(da,&locala);CHKERRQ(ierr);
  ierr = DAGetCoordinates(da,&coors);CHKERRQ(ierr);
  ierr = VecGetArray(coors,&x);CHKERRQ(ierr);

  /* Set values into global vectors */
  ierr = VecGetArray(global,&alocal);CHKERRQ(ierr);
  ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr);
  n    = n/dof;
  for (j=0; j<dof; j++) {
    for (i=0; i<n; i++) {
      alocal[j+dof*i] = PetscSinScalar(2*PETSC_PI*(j+1)*x[i]); 
    }
  }
  ierr = VecRestoreArray(global,&alocal);CHKERRQ(ierr);
  ierr = VecRestoreArray(coors,&x);CHKERRQ(ierr);
  ierr = VecDestroy(coords);CHKERRQ(ierr);

  ierr = VecView(global,viewer);CHKERRQ(ierr); 

  /* Send ghost points to local vectors */
  ierr = DAGlobalToLocalBegin(da,global,INSERT_VALUES,locala);CHKERRQ(ierr);
  ierr = DAGlobalToLocalEnd(da,global,INSERT_VALUES,locala);CHKERRQ(ierr);

  /* Free memory */
  ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
  ierr = VecDestroy(global);CHKERRQ(ierr);
  ierr = VecDestroy(local);CHKERRQ(ierr);
  ierr = VecDestroy(locala);CHKERRQ(ierr);
  ierr = DADestroy(da);CHKERRQ(ierr);
  ierr = PetscFinalize();CHKERRQ(ierr);
  return 0;
}
Exemple #23
0
/* 
   FormFunction - Evaluates nonlinear function, F(x).

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

   Output Parameter:
.  f - function vector

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

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

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

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

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

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

  /*
     Restore vectors
  */
  ierr = DAVecRestoreArray(da,xlocal,&xx);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(da,f,&ff);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(da,user->F,&FF);CHKERRQ(ierr);
  ierr = DARestoreLocalVector(da,&xlocal);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #24
0
int main(int argc,char **argv)
{
  DMMG           *dmmg_comp;          /* multilevel grid structure */
  AppCtx         user;                /* user-defined work context */
  PetscInt       mx,my,its,max_its,i;
  PetscErrorCode ierr;
  MPI_Comm       comm;
  SNES           snes;
  DA             da1,da2;
  DMComposite    pack;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  ierr = VecDestroy(X1_local);CHKERRQ(ierr);
  ierr = VecDestroy(X2_local);CHKERRQ(ierr);
  ierr = PetscFinalize();CHKERRQ(ierr);
  return 0;
}
Exemple #25
0
static int TaoDA2dLoopADFunctionGradient(TAO_APPLICATION tao, DA da, Vec X, double *f, Vec G, void * ctx) {

  TaoDA2D4DOFADICFGCtx *myapp = (TaoDA2D4DOFADICFGCtx*) ctx;
  MPI_Comm comm;
  Vec localX, localG;
  int info, i, j, coor[2];
  int xs, xm, mx, xe, ys, ym, ye, my;
  PetscScalar zero=0.0, floc = 0.0;
  DERIV_TYPE adF,*adX=myapp->adX;
  Field     **x,**g;

  info = DAGetLocalVector(da, &localX); CHKERRQ(info);
  info = DAGetLocalVector(da, &localG); CHKERRQ(info);
  info = VecSet(G, zero); CHKERRQ(info);
  info = VecSet(localG, zero); CHKERRQ(info);

  info = DAGetInfo(da,PETSC_NULL,&mx,&my,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,
		   PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(info);

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

  info = DAVecGetArray(da, localX, (void**)&x); CHKERRQ(info);
  info = DAVecGetArray(da, localG, (void**)&g); CHKERRQ(info);

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

  xe = xs + xm;
  ye = ys + ym;

  for (j = ys; j < ye; j++) {
    for (i = xs; i < xe; i++) {

        DERIV_val(adX[0]) = x[j][i].x;
        DERIV_val(adX[1]) = x[j][i].y;
        DERIV_val(adX[2]) = x[j][i].vpotx;
        DERIV_val(adX[3]) = x[j][i].vpoty;

        DERIV_val(adX[4]) = x[j][i+1].x;
        DERIV_val(adX[5]) = x[j][i+1].y;
        DERIV_val(adX[6]) = x[j][i+1].vpotx;
        DERIV_val(adX[7]) = x[j][i+1].vpoty;

        DERIV_val(adX[8]) = x[j+1][i].x;
        DERIV_val(adX[9]) = x[j+1][i].y;
        DERIV_val(adX[10]) = x[j+1][i].vpotx;

        DERIV_val(adX[11]) = x[j+1][i].vpoty;

        DERIV_val(adX[12]) = x[j+1][i+1].x;
        DERIV_val(adX[13]) = x[j+1][i+1].y;
        DERIV_val(adX[14]) = x[j+1][i+1].vpotx;
        DERIV_val(adX[15]) = x[j+1][i+1].vpoty;

        coor[0] = i; coor[1] = j;

        info = myapp->computeadicfunctiongradient(coor,adX,&adF,myapp->elementfgctx);
	CHKERRQ(info);

        floc += DERIV_val(adF);

        g[j][i].x += DERIV_grad(adF)[0];
        g[j][i].y += DERIV_grad(adF)[1];
        g[j][i].vpotx += DERIV_grad(adF)[2];
        g[j][i].vpoty += DERIV_grad(adF)[3];

        g[j][i+1].x += DERIV_grad(adF)[4];
        g[j][i+1].y += DERIV_grad(adF)[5];
        g[j][i+1].vpotx += DERIV_grad(adF)[6];
        g[j][i+1].vpoty += DERIV_grad(adF)[7];

        g[j+1][i].x += DERIV_grad(adF)[8];
        g[j+1][i].y += DERIV_grad(adF)[9];
	g[j+1][i].vpotx += DERIV_grad(adF)[10];

	g[j+1][i].vpoty += DERIV_grad(adF)[11];

        g[j+1][i+1].x += DERIV_grad(adF)[12];
        g[j+1][i+1].y += DERIV_grad(adF)[13];
        g[j+1][i+1].vpotx += DERIV_grad(adF)[14];
        g[j+1][i+1].vpoty += DERIV_grad(adF)[15];

    }
  }


  info = DAVecRestoreArray(da, localX, (void**)&x); CHKERRQ(info);
  info = DAVecRestoreArray(da, localG, (void**)&g); CHKERRQ(info);

  info = DALocalToGlobalBegin(da, localG, G); CHKERRQ(info);
  info = DARestoreLocalVector(da, &localX); CHKERRQ(info);
  info = DARestoreLocalVector(da, &localG); CHKERRQ(info);
  info = DALocalToGlobalEnd(da, localG, G); CHKERRQ(info);

  PetscLogFlops((ye-ys)*(xe-xs)*(myapp->elementfgflops + 33));
  PetscObjectGetComm((PetscObject)da,&comm); CHKERRQ(info);
  info = MPI_Allreduce(&floc, f, 1, MPI_DOUBLE, MPI_SUM, comm); CHKERRQ(info);

  PetscFunctionReturn(0);
} /* TaoDA2dLoopADFunctionGradient */
Exemple #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;

}
int Smoothing(Vec *x, Vec *y, PetscScalar *cacheScalar, PetscInt *cacheInt , VecScatter *ctx,PetscInt n,DA myDA, PetscInt Istart, PetscInt Iend){


PetscScalar    C0,C1,C2;
PetscErrorCode ierr;
PetscInt       localsizex;
PetscInt       n2,i, j, k; 
Vec            lvecx,lvecy;
PetscScalar    **lvecptx,**lvecpty;
Vec            bcvec;
IS             isbc;
//VecScatter     ctx;
PetscScalar    *bcpt1,*bcpt2,*bcpt3,*bcpt4;



localsizex    = Iend-Istart;

  C0 = 1.0/8;
  C1 = 1*1.0/4;
  C2 = 1*3.0/16;

n2     = (PetscInt)(n*0.5);


DACreateLocalVector(myDA,&lvecx);
DACreateLocalVector(myDA,&lvecy);
DAGlobalToLocalBegin(myDA,*x,INSERT_VALUES,lvecx);
DAGlobalToLocalEnd(myDA,*x,INSERT_VALUES,lvecx);



VecGetArray2d(lvecx,localsizex+4,n2+4,0,0,&lvecptx);
VecGetArray2d(lvecy,localsizex+4,n2+4,0,0,&lvecpty);

// X direction smoothing
for(j=0;j<n2+4;j++){
   for(i=2;i<localsizex+2;i++){

   lvecpty[i][j] = C0*lvecptx[i][j]
                  +C1*lvecptx[i-1][j] +C1*lvecptx[i+1][j]
                  +C2*lvecptx[i-2][j]+C2*lvecptx[i+2][j];             
   }   
}


VecCreateSeqWithArray(MPI_COMM_SELF,localsizex*4,cacheScalar,&bcvec);
VecScatterBegin(*x,bcvec,INSERT_VALUES,SCATTER_FORWARD,*ctx);
VecScatterEnd(*x,bcvec,INSERT_VALUES,SCATTER_FORWARD,*ctx);


bcpt1 = cacheScalar;
bcpt2 = cacheScalar+localsizex;
bcpt3 = cacheScalar+localsizex*2;
bcpt4 = cacheScalar+localsizex*3;

k= 0;
for(i=2;i<localsizex+2;i++){
 
  lvecpty[i][0]= *(bcpt3+k);
  lvecpty[i][1]= *(bcpt4+k);
  lvecpty[i][n2+3]= *(bcpt2+k);
  lvecpty[i][n2+2]= *(bcpt1+k);

  k++;
}

// Y direction smoothing
for(j=2;j<n2+2;j++){
   for(i=2;i<localsizex+2;i++){
   lvecptx[i][j] = C0*lvecpty[i][j]
                  +C1*lvecpty[i][j-1] +C1*lvecpty[i][j+1]
                  +C2*lvecpty[i][j-2] +C2*lvecpty[i][j+2];               
   }   
}


VecRestoreArray2d(lvecy,localsizex+4,n2+4,0,0,&lvecpty);
VecRestoreArray2d(lvecx,localsizex+4,n2+4,0,0,&lvecptx);

DALocalToGlobal(myDA,lvecx,INSERT_VALUES,*x);

VecDestroy(bcvec);
VecDestroy(lvecx);
VecDestroy(lvecy);

return 0;
}
Exemple #28
0
/*
   FormJacobian - Evaluates Jacobian matrix.

   Input Parameters:
.  ot - the OT context
.  x - input vector
.  ptr - optional user-defined context, as set by OTSetJacobian()

   Output Parameters:
.  A - Jacobian matrix
.  B - optionally different preconditioning matrix
.  flag - flag indicating matrix structure

   Notes:
   Due to grid point reordering with DAs, we must always work
   with the local grid points, and then transform them to the new
   global numbering with the "ltog" mapping (via DAGetGlobalIndices()).
   We cannot work directly with the global numbers for the original
   uniprocessor grid!  

   Two methods are available for imposing this transformation
   when setting matrix entries:
     (A) MatSetValuesLocal(), using the local ordering (including
         ghost points!)
         - Use DAGetGlobalIndices() to extract the local-to-global map
         - Associate this map with the matrix by calling
           MatSetLocalToGlobalMapping() once
         - Set matrix entries using the local ordering
           by calling MatSetValuesLocal()
     (B) MatSetValues(), using the global ordering 
         - Use DAGetGlobalIndices() to extract the local-to-global map
         - Then apply this map explicitly yourself
         - Set matrix entries using the global ordering by calling
           MatSetValues()
   Option (A) seems cleaner/easier in many cases, and is the procedure
   used in this example.
*/
int FormJacobian(TAO_SOLVER ot,Vec X,Mat *JJ,void *ptr)
{
  AppCtx  *user = (AppCtx *) ptr;  /* user-defined application context */
  Mat     jac=*JJ;
  Vec     localX=user->localX; // local vector
  int     info, i, j, row, mx, my, col[5];
  int     xs, ys, xm, ym, gxs, gys, gxm, gym;
  PetscScalar  two = 2.0, one = 1.0, lambda, v[5], hx, hy, hxdhy, hydhx, sc, *x;
  

  mx = user->mx;            my = user->my;            lambda = user->param;
  hx = one/(double)(mx-1);  hy = one/(double)(my-1);
  sc = hx*hy;               hxdhy = hx/hy;            hydhx = hy/hx;

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

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

  /*
     Get pointer to vector data
  */
  info = VecGetArray(localX,&x); CHKERRQ(info);


  /*
     Get local grid 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);

  /* 
     Compute entries for the locally owned part of the Jacobian.
      - Currently, all PETSc parallel matrix formats are partitioned by
        contiguous chunks of rows across the processors. 
      - Each processor needs to insert only elements that it owns
        locally (but any non-local elements will be sent to the
        appropriate processor during matrix assembly). 
      - Here, we set all entries for a particular row at once.
      - We can set matrix entries either using either
        MatSetValuesLocal() or MatSetValues(), as discussed above.
  */
  for (j=ys; j<ys+ym; j++) {
    row = (j - gys)*gxm + xs - gxs - 1; 
    for (i=xs; i<xs+xm; i++) {
      row++;
      /* boundary points */
      if (i == 0 || j == 0 || i == mx-1 || j == my-1 ) {
        info = MatSetValuesLocal(jac,1,&row,1,&row,&one,INSERT_VALUES); CHKERRQ(info);
        continue;
      }
      /* interior grid points */
      v[0] = -hxdhy; col[0] = row - gxm;
      v[1] = -hydhx; col[1] = row - 1;
      v[2] = two*(hydhx + hxdhy) - sc*lambda*exp(x[row]); col[2] = row;
      v[3] = -hydhx; col[3] = row + 1;
      v[4] = -hxdhy; col[4] = row + gxm;
      info = MatSetValuesLocal(jac,1,&row,5,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(jac,MAT_FINAL_ASSEMBLY); CHKERRQ(info);
  info = VecRestoreArray(localX,&x); CHKERRQ(info);
  info = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY); CHKERRQ(info);

  /*
     Set flag to indicate that the Jacobian matrix retains an identical
     nonzero structure throughout all nonlinear iterations (although the
     values of the entries change). Thus, we can save some work in setting
     up the preconditioner (e.g., no need to redo symbolic factorization for
     ILU/ICC preconditioners).
      - If the nonzero structure of the matrix is different during
        successive linear solves, then the flag DIFFERENT_NONZERO_PATTERN
        must be used instead.  If you are unsure whether the matrix
        structure has changed or not, use the flag DIFFERENT_NONZERO_PATTERN.
      - Caution:  If you specify SAME_NONZERO_PATTERN, PETSc
        believes your assertion and does not check the structure
        of the matrix.  If you erroneously claim that the structure
        is the same when it actually is not, the new preconditioner
        will not function correctly.  Thus, use this optimization
        feature with caution!
  */

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

  return 0;
}
Exemple #29
0
static PetscErrorCode BodFunctionLocal(DALocalInfo *info, Node *Hu, Node *f, AppCtx *user)
{
  PetscErrorCode ierr;
  PetscReal      rg = user->rho * user->g, dx = user->dx;
  PetscScalar    *M, *Bstag, *beta,
                 duH, ul, u, ur, dHdx, Fl, Fr, Tl, Tr;
  PetscInt       i, Mx = info->mx;
  Vec            locBstag;

  PetscFunctionBegin;

  /* we need stencil width on Bstag (but not for M, beta) */
  ierr = DAGetLocalVector(user->scalarda,&locBstag);CHKERRQ(ierr);  /* do NOT destroy it */
  ierr = DAGlobalToLocalBegin(user->scalarda,user->Bstag,INSERT_VALUES,locBstag); CHKERRQ(ierr);
  ierr = DAGlobalToLocalEnd(user->scalarda,user->Bstag,INSERT_VALUES,locBstag); CHKERRQ(ierr);

  ierr = DAVecGetArray(user->scalarda,locBstag,&Bstag);CHKERRQ(ierr);
  ierr = DAVecGetArray(user->scalarda,user->M,&M);CHKERRQ(ierr);
  ierr = DAVecGetArray(user->scalarda,user->beta,&beta);CHKERRQ(ierr);
  for (i = info->xs; i < info->xs + info->xm; i++) {
  
    /* MASS CONT */
    if (i == 0) {
      /* residual at left-most point is Dirichlet cond. */
      f[0].H = Hu[0].H - user->H0;
    } else {
      /* centered difference IS UNSTABLE:
        duH = Hu[i+1].u * Hu[i+1].H - ( (i == 1) ? 0.0 : Hu[i-1].u * Hu[i-1].H );
        duH *= 0.5; */

      if (user->upwind1) {
        /* 1st-order upwind; leftward difference because u > 0 (because dH/dx < 0) */
        duH = Hu[i].u * Hu[i].H - ( (i == 1) ? 0.0 : Hu[i-1].u * Hu[i-1].H );
      } else {
        /* 2nd-order upwind; see Beam-Warming discussion in R. LeVeque, "Finite Volume ..." */
        if (i == 1) { /* use PDE  M - (uH)_x = 0 to get quadratic poly, then diff that */
          duH = - dx * M[0] + 2.0 * Hu[1].u * Hu[1].H;
        } else {
          duH = 3.0 * Hu[i].u * Hu[i].H - 4.0 * Hu[i-1].u * Hu[i-1].H;
          /* if i == 2 then u=0 so uH = 0 */
          if (i >= 3)  duH += Hu[i-2].u * Hu[i-2].H;
          duH *= 0.5;
        }
      }

      f[i].H = dx * M[i] - duH;
    }

    /* SSA */
    if (i == 0) {
      /* residual at left-most point is Dirichlet cond. */
      f[0].u = Hu[0].u - 0.0;
    } else {
      /* residual: SSA eqn */
      /* consecutive values of u */
      ul = (i == 1) ? 0.0 : Hu[i-1].u;
      u  = Hu[i].u;
      ur = (i == Mx-1) ? -1.1e30 : Hu[i+1].u;
      /* surface slope */
      if (i == 1) { 
        dHdx  = (Hu[i+1].H - user->H0) / (2.0 * dx);
      } else if (i == Mx-1) {
        /* nearly 2nd-order global convergence seems to occur even with this:
             dHdx  = (Hu[i].H - Hu[i-1].H) / dx; */
        dHdx  = (3.0*Hu[i].H - 4.0*Hu[i-1].H + Hu[i-2].H) / (2.0 * dx);
      } else { /* generic case */
        dHdx  = (Hu[i+1].H - Hu[i-1].H) / (2.0 * dx);
      }
      /* vertically-integrated longitudinal stress */
      Fl = GetFSR(dx,user->epsilon,user->n, ul,u);
      if (i == Mx-1) {
        Tl = 2.0 * (Hu[i-1].H + Hu[i].H) * Bstag[i-1] * Fl;
        Tr = (1.0 - user->rho / user->rhow) * user->rho * user->g * Hu[i].H * Hu[i].H;
        /* exact value: Tr = 2.0 * user->Txc; */
      } else {
        Fr = GetFSR(dx,user->epsilon,user->n, u,ur);
        Tl = (Hu[i-1].H + Hu[i].H) * Bstag[i-1] * Fl;
        Tr = (Hu[i].H + Hu[i+1].H) * Bstag[i] * Fr;        
      }

      f[i].u = (Tr - Tl) - dx * beta[i] * u - dx * rg * Hu[i].H * dHdx; /* SSA */

    }
  }
  ierr = DAVecRestoreArray(user->scalarda,locBstag,&Bstag);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(user->scalarda,user->M,&M);CHKERRQ(ierr);
  ierr = DAVecRestoreArray(user->scalarda,user->beta,&beta);CHKERRQ(ierr);

  ierr = DARestoreLocalVector(user->scalarda,&locBstag);CHKERRQ(ierr);

  PetscFunctionReturn(0);
}
Exemple #30
0
/*
  WholeMSurfFunctionGradient - Evaluates function and gradient over the 
      whole grid

  Input:
    daapplication - TAO application object
    da  - distributed array
    X   - the current point, at which the function and gradient are evaluated
    ptr - user-defined application context

  Output:
    f - value of the objective funtion at X
    G - gradient at X
*/
static int WholeMSurfFunctionGradient(TAO_APPLICATION daapplication, DA da, Vec X, double *f, Vec G, void *ptr) {

  AppCtx *user = (AppCtx*)ptr;
  Vec localX, localG;
  PetscInt i, j;
  int info;
  PetscInt xs, xm, gxs, gxm, xe, ys, ym, gys, gym, ye;
  double **x, **g;
  double floc = 0.0;
  PetscScalar zero = 0.0;

  double hx, hy, area;
  double dvdx, dvdy, flow, fup;
  double areadivf;

  hx = user->hx;
  hy = user->hy;
  area = user->area;

  info = DAGetLocalVector(da, &localX); CHKERRQ(info);
  info = DAGetLocalVector(da, &localG); CHKERRQ(info);
  info = VecSet(G, zero); CHKERRQ(info);
  info = VecSet(localG, zero); CHKERRQ(info);

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

  info = DAVecGetArray(da, localX, (void**)&x); CHKERRQ(info);
  info = DAVecGetArray(da, localG, (void**)&g); CHKERRQ(info);

  info = DAGetCorners(da, &xs, &ys, TAO_NULL, &xm, &ym, TAO_NULL); CHKERRQ(info);
  info = DAGetGhostCorners(da, &gxs, &gys, TAO_NULL, &gxm, &gym, TAO_NULL); CHKERRQ(info);

  xe = gxs + gxm - 1;
  ye = gys + gym - 1;
  for (j = ys; j < ye; j++) {
    for (i = xs; i < xe; i++) {

      /* lower triangle contribution */
      dvdx = (x[j][i] - x[j][i+1]) / hx;  
      dvdy = (x[j][i] - x[j+1][i]) / hy;
      flow = sqrt( 1 + dvdx * dvdx + dvdy * dvdy );
      areadivf = area / flow;
      g[j][i] += (dvdx / hx + dvdy / hy) * areadivf;
      g[j][i+1] += (-dvdx / hx) * areadivf;
      g[j+1][i] += (-dvdy / hy) * areadivf;

      /* upper triangle contribution */
      dvdx = (x[j+1][i+1] - x[j+1][i]) / hx;
      dvdy = (x[j+1][i+1] - x[j][i+1]) / hy;
      fup = sqrt( 1 + dvdx * dvdx + dvdy * dvdy );
      areadivf = area / fup;
      g[j][i+1] += (-dvdy / hy) * areadivf;
      g[j+1][i] += (-dvdx / hx) * areadivf;
      g[j+1][i+1] += (dvdx / hx + dvdy / hy) * areadivf;

      floc += area * (flow + fup);

    }
  }

  info = MPI_Allreduce(&floc, f, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); CHKERRQ(info);

  info = DAVecRestoreArray(da, localX, (void**)&x); CHKERRQ(info);
  info = DAVecRestoreArray(da, localG, (void**)&g); CHKERRQ(info);

  info = DALocalToGlobalBegin(da, localG, G); CHKERRQ(info);
  info = DALocalToGlobalEnd(da, localG, G); CHKERRQ(info);

  info = DARestoreLocalVector(da, &localX); CHKERRQ(info);
  info = DARestoreLocalVector(da, &localG); CHKERRQ(info);

  info = PetscLogFlops((xe-xs) * (ye-ys) * 42); CHKERRQ(info);

  return 0;
} /* WholeMSurfFunctionGradient  */