本文整理汇总了C++中DMGlobalToLocalEnd函数的典型用法代码示例。如果您正苦于以下问题:C++ DMGlobalToLocalEnd函数的具体用法?C++ DMGlobalToLocalEnd怎么用?C++ DMGlobalToLocalEnd使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了DMGlobalToLocalEnd函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: F
/*
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;
DM da = user->da;
PetscScalar *xx,*ff,*FF,d;
PetscErrorCode ierr;
PetscInt i,M,xs,xm;
Vec xlocal;
PetscFunctionBeginUser;
ierr = DMGetLocalVector(da,&xlocal);CHKERRQ(ierr);
/*
Scatter ghost points to local vector, using the 2-step process
DMGlobalToLocalBegin(), DMGlobalToLocalEnd().
By placing code between these two statements, computations can
be done while messages are in transition.
*/
ierr = DMGlobalToLocalBegin(da,x,INSERT_VALUES,xlocal);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(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 DMDAVecGetArray() allows accessing the values using global ordering
*/
ierr = DMDAVecGetArray(da,xlocal,&xx);CHKERRQ(ierr);
ierr = DMDAVecGetArray(da,f,&ff);CHKERRQ(ierr);
ierr = DMDAVecGetArray(da,user->F,&FF);CHKERRQ(ierr);
/*
Get local grid boundaries (for 1-dimensional DMDA):
xs, xm - starting grid index, width of local grid (no ghost points)
*/
ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr);
ierr = DMDAGetInfo(da,NULL,&M,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,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 = DMDAVecRestoreArray(da,xlocal,&xx);CHKERRQ(ierr);
ierr = DMDAVecRestoreArray(da,f,&ff);CHKERRQ(ierr);
ierr = DMDAVecRestoreArray(da,user->F,&FF);CHKERRQ(ierr);
ierr = DMRestoreLocalVector(da,&xlocal);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例2: TSetRHSJacobian
/*
RHSJacobian - User-provided routine to compute the Jacobian of
the nonlinear right-hand-side function of the ODE.
Input Parameters:
ts - the TS context
t - current time
global_in - global input vector
dummy - optional user-defined context, as set by TSetRHSJacobian()
Output Parameters:
AA - Jacobian matrix
BB - optionally different preconditioning matrix
str - flag indicating matrix structure
Notes:
RHSJacobian computes 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).
- Always specify global row and columns of matrix entries when
using MatSetValues().
- Here, we set all entries for a particular row at once.
- Note that MatSetValues() uses 0-based row and column numbers
in Fortran as well as in C.
*/
PetscErrorCode RHSJacobian(TS ts,PetscReal t,Vec global_in,Mat *AA,Mat *BB,MatStructure *str,void *ctx)
{
Mat B = *BB; /* Jacobian matrix */
AppCtx *appctx = (AppCtx*)ctx; /* user-defined application context */
Vec local_in = appctx->u_local; /* local ghosted input vector */
DM da = appctx->da; /* distributed array */
PetscScalar v[3],*localptr,sc;
PetscErrorCode ierr;
PetscInt i,mstart,mend,mstarts,mends,idx[3],is;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Get ready for local Jacobian computations
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
Scatter ghost points to local vector, using the 2-step process
DMGlobalToLocalBegin(), DMGlobalToLocalEnd().
By placing code between these two statements, computations can be
done while messages are in transition.
*/
ierr = DMGlobalToLocalBegin(da,global_in,INSERT_VALUES,local_in);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,global_in,INSERT_VALUES,local_in);CHKERRQ(ierr);
/*
Get pointer to vector data
*/
ierr = VecGetArray(local_in,&localptr);CHKERRQ(ierr);
/*
Get starting and ending locally owned rows of the matrix
*/
ierr = MatGetOwnershipRange(B,&mstarts,&mends);CHKERRQ(ierr);
mstart = mstarts; mend = mends;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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().
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
Set matrix rows corresponding to boundary data
*/
if (mstart == 0) {
v[0] = 0.0;
ierr = MatSetValues(B,1,&mstart,1,&mstart,v,INSERT_VALUES);CHKERRQ(ierr);
mstart++;
}
if (mend == appctx->m) {
mend--;
v[0] = 0.0;
ierr = MatSetValues(B,1,&mend,1,&mend,v,INSERT_VALUES);CHKERRQ(ierr);
}
/*
Set matrix rows corresponding to interior data. We construct the
matrix one row at a time.
*/
sc = 1.0/(appctx->h*appctx->h*2.0*(1.0+t)*(1.0+t));
for (i=mstart; i<mend; i++) {
idx[0] = i-1; idx[1] = i; idx[2] = i+1;
is = i - mstart + 1;
v[0] = sc*localptr[is];
v[1] = sc*(localptr[is+1] + localptr[is-1] - 4.0*localptr[is]);
v[2] = sc*localptr[is];
ierr = MatSetValues(B,1,&i,3,idx,v,INSERT_VALUES);CHKERRQ(ierr);
}
//.........这里部分代码省略.........
示例3: ComputeJacobian
/*
ComputeJacobian - Evaluates Jacobian matrix.
Input Parameters:
. x - input vector
. user - user-defined application context
Output Parameters:
. jac - Jacobian matrix
. flag - flag indicating matrix structure
Notes:
Due to grid point reordering with DMDAs, we must always work
with the local grid points, and then transform them to the new
global numbering with the "ltog" mapping
We cannot work directly with the global numbers for the original
uniprocessor grid!
*/
PetscErrorCode ComputeJacobian(AppCtx *user,Vec X,Mat jac)
{
PetscErrorCode ierr;
Vec localX = user->localX; /* local vector */
const PetscInt *ltog; /* local-to-global mapping */
PetscInt i,j,row,mx,my,col[5];
PetscInt xs,ys,xm,ym,gxs,gys,gxm,gym,grow;
PetscScalar two = 2.0,one = 1.0,lambda,v[5],hx,hy,hxdhy,hydhx,sc,*x;
ISLocalToGlobalMapping ltogm;
mx = user->mx; my = user->my; lambda = user->param;
hx = one/(PetscReal)(mx-1); hy = one/(PetscReal)(my-1);
sc = hx*hy; hxdhy = hx/hy; hydhx = hy/hx;
/*
Scatter ghost points to local vector, using the 2-step process
DMGlobalToLocalBegin(), DMGlobalToLocalEnd().
By placing code between these two statements, computations can be
done while messages are in transition.
*/
ierr = DMGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
/*
Get pointer to vector data
*/
ierr = VecGetArray(localX,&x);CHKERRQ(ierr);
/*
Get local grid boundaries
*/
ierr = DMDAGetCorners(user->da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr);
ierr = DMDAGetGhostCorners(user->da,&gxs,&gys,NULL,&gxm,&gym,NULL);CHKERRQ(ierr);
/*
Get the global node numbers for all local nodes, including ghost points
*/
ierr = DMGetLocalToGlobalMapping(user->da,<ogm);CHKERRQ(ierr);
ierr = ISLocalToGlobalMappingGetIndices(ltogm,<og);CHKERRQ(ierr);
/*
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. The "grow"
parameter computed below specifies the global row number
corresponding to each local grid point.
- 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).
- Always specify global row and columns of matrix entries.
- Here, we set all entries for a particular row at once.
*/
for (j=ys; j<ys+ym; j++) {
row = (j - gys)*gxm + xs - gxs - 1;
for (i=xs; i<xs+xm; i++) {
row++;
grow = ltog[row];
/* boundary points */
if (i == 0 || j == 0 || i == mx-1 || j == my-1) {
ierr = MatSetValues(jac,1,&grow,1,&grow,&one,INSERT_VALUES);CHKERRQ(ierr);
continue;
}
/* interior grid points */
v[0] = -hxdhy; col[0] = ltog[row - gxm];
v[1] = -hydhx; col[1] = ltog[row - 1];
v[2] = two*(hydhx + hxdhy) - sc*lambda*PetscExpScalar(x[row]); col[2] = grow;
v[3] = -hydhx; col[3] = ltog[row + 1];
v[4] = -hxdhy; col[4] = ltog[row + gxm];
ierr = MatSetValues(jac,1,&grow,5,col,v,INSERT_VALUES);CHKERRQ(ierr);
}
}
ierr = ISLocalToGlobalMappingRestoreIndices(ltogm,<og);CHKERRQ(ierr);
/*
Assemble matrix, using the 2-step process:
MatAssemblyBegin(), MatAssemblyEnd().
By placing code between these two statements, computations can be
done while messages are in transition.
*/
ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = VecRestoreArray(localX,&x);CHKERRQ(ierr);
ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
//.........这里部分代码省略.........
示例4: FormFunctionGradient
PetscErrorCode FormFunctionGradient(Tao tao, Vec X, PetscReal *fcn,Vec G,void *ptr)
{
AppCtx* user=(AppCtx*)ptr;
PetscErrorCode ierr;
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);
ierr = DMGetLocalVector(user->dm,&localX);CHKERRQ(ierr);
ierr = DMGlobalToLocalBegin(user->dm,X,INSERT_VALUES,localX);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(user->dm,X,INSERT_VALUES,localX);CHKERRQ(ierr);
ierr = VecSet(G, zero);CHKERRQ(ierr);
/*
Get local grid boundaries
*/
ierr = DMDAGetCorners(user->dm,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr);
ierr = DMDAGetGhostCorners(user->dm,&gxs,&gys,NULL,&gxm,&gym,NULL);CHKERRQ(ierr);
ierr = VecGetArray(localX,&x);CHKERRQ(ierr);
ierr = VecGetArray(G,&g);CHKERRQ(ierr);
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;
}
}
ierr = VecRestoreArray(localX,&x);CHKERRQ(ierr);
ierr = VecRestoreArray(G,&g);CHKERRQ(ierr);
ierr = DMRestoreLocalVector(user->dm,&localX);CHKERRQ(ierr);
ierr = VecDot(X,G,&f1);CHKERRQ(ierr);
ierr = VecDot(user->B,X,&f2);CHKERRQ(ierr);
ierr = VecAXPY(G, one, user->B);CHKERRQ(ierr);
*fcn = f1/2.0 + f2;
ierr = PetscLogFlops((91 + 10*ym) * xm);CHKERRQ(ierr);
return 0;
//.........这里部分代码省略.........
示例5: FormIFunction
PetscErrorCode FormIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
{
PetscErrorCode ierr;
AppCtx *user=(AppCtx*)ctx;
DM da = (DM)user->da;
PetscInt i,j,Mx,My,xs,ys,xm,ym;
PetscReal hx,hy,sx,sy;
PetscScalar u,uxx,uyy,**uarray,**f,**udot;
Vec localU;
PetscFunctionBeginUser;
ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr);
ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,
PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx);
hy = 1.0/(PetscReal)(My-1); sy = 1.0/(hy*hy);
if (user->nstencilpts == 9 && hx != hy)SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"hx must equal hy when nstencilpts = 9 for this example");
/*
Scatter ghost points to local vector,using the 2-step process
DMGlobalToLocalBegin(),DMGlobalToLocalEnd().
By placing code between these two statements, computations can be
done while messages are in transition.
*/
ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr);
/* Get pointers to vector data */
ierr = DMDAVecGetArray(da,localU,&uarray);CHKERRQ(ierr);
ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr);
ierr = DMDAVecGetArray(da,Udot,&udot);CHKERRQ(ierr);
/* Get local grid boundaries */
ierr = DMDAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr);
/* Compute function over the locally owned part of the grid */
for (j=ys; j<ys+ym; j++) {
for (i=xs; i<xs+xm; i++) {
/* Boundary conditions */
if (i == 0 || j == 0 || i == Mx-1 || j == My-1) {
if (user->boundary == 0){ /* Drichlet BC */
f[j][i] = uarray[j][i]; /* F = U */
} else { /* Neumann BC */
if (i == 0 && j == 0){ /* SW corner */
f[j][i] = uarray[j][i] - uarray[j+1][i+1];
} else if (i == Mx-1 && j == 0){ /* SE corner */
f[j][i] = uarray[j][i] - uarray[j+1][i-1];
} else if (i == 0 && j == My-1){ /* NW corner */
f[j][i] = uarray[j][i] - uarray[j-1][i+1];
} else if (i == Mx-1 && j == My-1){ /* NE corner */
f[j][i] = uarray[j][i] - uarray[j-1][i-1];
} else if (i == 0){ /* Left */
f[j][i] = uarray[j][i] - uarray[j][i+1];
} else if (i == Mx-1){ /* Right */
f[j][i] = uarray[j][i] - uarray[j][i-1];
} else if (j == 0) { /* Bottom */
f[j][i] = uarray[j][i] - uarray[j+1][i];
} else if (j == My-1){ /* Top */
f[j][i] = uarray[j][i] - uarray[j-1][i];
}
}
} else { /* Interior */
u = uarray[j][i];
/* 5-point stencil */
uxx = (-2.0*u + uarray[j][i-1] + uarray[j][i+1]);
uyy = (-2.0*u + uarray[j-1][i] + uarray[j+1][i]);
if (user->nstencilpts == 9){
/* 9-point stencil: assume hx=hy */
uxx = 2.0*uxx/3.0 + (0.5*(uarray[j-1][i-1]+uarray[j-1][i+1]+uarray[j+1][i-1]+uarray[j+1][i+1]) - 2.0*u)/6.0;
uyy = 2.0*uyy/3.0 + (0.5*(uarray[j-1][i-1]+uarray[j-1][i+1]+uarray[j+1][i-1]+uarray[j+1][i+1]) - 2.0*u)/6.0;
}
f[j][i] = udot[j][i] - (uxx*sx + uyy*sy);
}
}
}
/* Restore vectors */
ierr = DMDAVecRestoreArray(da,localU,&uarray);CHKERRQ(ierr);
ierr = DMDAVecRestoreArray(da,F,&f);CHKERRQ(ierr);
ierr = DMDAVecRestoreArray(da,Udot,&udot);CHKERRQ(ierr);
ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr);
ierr = PetscLogFlops(11.0*ym*xm);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例6: FormFunction
PetscErrorCode FormFunction(SNES snes,Vec X,Vec F,void *ptr)
{
AppCtx *user = (AppCtx*)ptr;
PetscErrorCode ierr;
PetscInt i,j,mx,my,xs,ys,xm,ym;
PetscScalar zero = 0.0,one = 1.0;
PetscScalar hx,hy,hxdhy,hydhx;
PetscScalar t0,tn,ts,te,tw,an,as,ae,aw,dn,ds,de,dw,fn = 0.0,fs = 0.0,fe =0.0,fw = 0.0;
PetscScalar tleft,tright,beta;
PetscScalar **x,**f;
Vec localX;
DM da;
PetscFunctionBeginUser;
ierr = SNESGetDM(snes,&da);CHKERRQ(ierr);
ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr);
ierr = DMDAGetInfo(da,NULL,&mx,&my,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
hx = one/(PetscReal)(mx-1); hy = one/(PetscReal)(my-1);
hxdhy = hx/hy; hydhx = hy/hx;
tleft = user->tleft; tright = user->tright;
beta = user->beta;
/* Get ghost points */
ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
ierr = DMDAGetCorners(da,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr);
ierr = DMDAVecGetArray(da,localX,&x);CHKERRQ(ierr);
ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr);
/* Evaluate function */
for (j=ys; j<ys+ym; j++) {
for (i=xs; i<xs+xm; i++) {
t0 = x[j][i];
if (i > 0 && i < mx-1 && j > 0 && j < my-1) {
/* general interior volume */
tw = x[j][i-1];
aw = 0.5*(t0 + tw);
dw = PetscPowScalar(aw,beta);
fw = dw*(t0 - tw);
te = x[j][i+1];
ae = 0.5*(t0 + te);
de = PetscPowScalar(ae,beta);
fe = de*(te - t0);
ts = x[j-1][i];
as = 0.5*(t0 + ts);
ds = PetscPowScalar(as,beta);
fs = ds*(t0 - ts);
tn = x[j+1][i];
an = 0.5*(t0 + tn);
dn = PetscPowScalar(an,beta);
fn = dn*(tn - t0);
} else if (i == 0) {
/* left-hand boundary */
tw = tleft;
aw = 0.5*(t0 + tw);
dw = PetscPowScalar(aw,beta);
fw = dw*(t0 - tw);
te = x[j][i+1];
ae = 0.5*(t0 + te);
de = PetscPowScalar(ae,beta);
fe = de*(te - t0);
if (j > 0) {
ts = x[j-1][i];
as = 0.5*(t0 + ts);
ds = PetscPowScalar(as,beta);
fs = ds*(t0 - ts);
} else fs = zero;
if (j < my-1) {
tn = x[j+1][i];
an = 0.5*(t0 + tn);
dn = PetscPowScalar(an,beta);
fn = dn*(tn - t0);
} else fn = zero;
} else if (i == mx-1) {
/* right-hand boundary */
tw = x[j][i-1];
aw = 0.5*(t0 + tw);
dw = PetscPowScalar(aw,beta);
fw = dw*(t0 - tw);
te = tright;
ae = 0.5*(t0 + te);
de = PetscPowScalar(ae,beta);
fe = de*(te - t0);
if (j > 0) {
ts = x[j-1][i];
//.........这里部分代码省略.........
示例7: CheckRedundancy
PetscErrorCode CheckRedundancy(SNES snes, IS act, IS *outact, DM da)
{
PetscErrorCode ierr;
PetscScalar **uin,**uout;
Vec UIN, UOUT;
PetscInt xs,xm,*outindex;
const PetscInt *index;
PetscInt k,i,l,n,M,cnt=0;
PetscFunctionBeginUser;
ierr = DMDAGetInfo(da,0,&M,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
ierr = DMGetGlobalVector(da,&UIN);CHKERRQ(ierr);
ierr = VecSet(UIN,0.0);CHKERRQ(ierr);
ierr = DMGetLocalVector(da,&UOUT);CHKERRQ(ierr);
ierr = DMDAVecGetArrayDOF(da,UIN,&uin);CHKERRQ(ierr);
ierr = ISGetIndices(act,&index);CHKERRQ(ierr);
ierr = ISGetLocalSize(act,&n);CHKERRQ(ierr);
for (k=0; k<n; k++) {
l = index[k]%5;
i = index[k]/5;
uin[i][l]=1.0;
}
printf("Number of active constraints before applying redundancy %d\n",n);
ierr = ISRestoreIndices(act,&index);CHKERRQ(ierr);
ierr = DMDAVecRestoreArrayDOF(da,UIN,&uin);CHKERRQ(ierr);
ierr = DMGlobalToLocalBegin(da,UIN,INSERT_VALUES,UOUT);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,UIN,INSERT_VALUES,UOUT);CHKERRQ(ierr);
ierr = DMDAVecGetArrayDOF(da,UOUT,&uout);CHKERRQ(ierr);
ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr);
for (i=xs; i < xs+xm;i++) {
if (uout[i-1][1] && uout[i][1] && uout[i+1][1]) uout[i][0] = 1.0;
if (uout[i-1][3] && uout[i][3] && uout[i+1][3]) uout[i][2] = 1.0;
}
for (i=xs; i < xs+xm; i++) {
for (l=0; l < 5; l++) {
if (uout[i][l]) cnt++;
}
}
printf("Number of active constraints after applying redundancy %d\n",cnt);
ierr = PetscMalloc(cnt*sizeof(PetscInt),&outindex);CHKERRQ(ierr);
cnt = 0;
for (i=xs; i < xs+xm;i++) {
for (l=0;l<5;l++) {
if (uout[i][l]) outindex[cnt++] = 5*(i)+l;
}
}
ierr = ISCreateGeneral(PETSC_COMM_WORLD,cnt,outindex,PETSC_OWN_POINTER,outact);CHKERRQ(ierr);
ierr = DMDAVecRestoreArrayDOF(da,UOUT,&uout);CHKERRQ(ierr);
ierr = DMRestoreGlobalVector(da,&UIN);CHKERRQ(ierr);
ierr = DMRestoreLocalVector(da,&UOUT);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例8: ComputeJacobian_LS
PetscErrorCode ComputeJacobian_LS(DM dm, Vec locX, PetscInt cell, PetscScalar CellValues[], void *ctx)
{
User user = (User) ctx;
Physics phys = user->model->physics;
PetscInt dof = phys->dof;
const PetscScalar *facegeom, *cellgeom,*x;
PetscErrorCode ierr;
DM dmFace, dmCell;
DM dmGrad = user->dmGrad;
PetscInt fStart, fEnd, face, cStart;
Vec locGrad, locGradLimiter, Grad;
/*here the localGradLimiter refers to the gradient that has been multiplied by the limiter function.
The locGradLimiter is used to construct the uL and uR, and the locGrad is used to caculate the diffusion term*/
Vec TempVec; /*a temperal vec for the vector restore*/
PetscFunctionBeginUser;
ierr = VecGetDM(user->facegeom,&dmFace);CHKERRQ(ierr);
ierr = VecGetDM(user->cellgeom,&dmCell);CHKERRQ(ierr);
ierr = DMGetGlobalVector(dmGrad,&Grad);CHKERRQ(ierr);
ierr = VecDuplicate(Grad, &TempVec);CHKERRQ(ierr);
ierr = VecCopy(Grad, TempVec);CHKERRQ(ierr);
/*Backup the original vector and use it to restore the value of dmGrad,
because I do not want to change the values of the cell gradient*/
ierr = VecGetArrayRead(user->facegeom,&facegeom);CHKERRQ(ierr);
ierr = VecGetArrayRead(user->cellgeom,&cellgeom);CHKERRQ(ierr);
ierr = VecGetArrayRead(locX,&x);CHKERRQ(ierr);
ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr);
{
PetscScalar *grad;
ierr = VecGetArray(Grad,&grad);CHKERRQ(ierr);
/* Limit interior gradients. Using cell-based loop because it generalizes better to vector limiters. */
const PetscInt *faces;
PetscInt numFaces,f;
PetscReal *cellPhi; /* Scalar limiter applied to each component separately */
const PetscScalar *cx;
const CellGeom *cg;
PetscScalar *cgrad;
PetscInt i;
ierr = PetscMalloc(phys->dof*sizeof(PetscScalar),&cellPhi);CHKERRQ(ierr);
ierr = DMPlexGetConeSize(dm,cell,&numFaces);CHKERRQ(ierr);
ierr = DMPlexGetCone(dm,cell,&faces);CHKERRQ(ierr);
ierr = DMPlexPointLocalRead(dm,cell,x,&cx);CHKERRQ(ierr);
ierr = DMPlexPointLocalRead(dmCell,cell,cellgeom,&cg);CHKERRQ(ierr);
ierr = DMPlexPointGlobalRef(dmGrad,cell,grad,&cgrad);CHKERRQ(ierr);
/* Limiter will be minimum value over all neighbors */
for (i=0; i<dof; i++) {
cellPhi[i] = PETSC_MAX_REAL;
}
for (f=0; f<numFaces; f++) {
const PetscScalar *ncx;
const CellGeom *ncg;
const PetscInt *fcells;
PetscInt face = faces[f],ncell;
PetscScalar v[DIM];
PetscBool ghost;
ierr = IsExteriorGhostFace(dm,face,&ghost);CHKERRQ(ierr);
if (ghost) continue;
ierr = DMPlexGetSupport(dm,face,&fcells);CHKERRQ(ierr);
ncell = cell == fcells[0] ? fcells[1] : fcells[0]; /*The expression (x ? y : z) has the value of y if x is nonzero, z otherwise */
ierr = DMPlexPointLocalRead(dm,ncell,x,&ncx);CHKERRQ(ierr);
ierr = DMPlexPointLocalRead(dmCell,ncell,cellgeom,&ncg);CHKERRQ(ierr);
Waxpy2(-1, cg->centroid, ncg->centroid, v);
for (i=0; i<dof; i++) {
/* We use the symmetric slope limited form of Berger, Aftosmis, and Murman 2005 */
PetscScalar phi,flim = 0.5 * (ncx[i] - cx[i]) / Dot2(&cgrad[i*DIM],v);
phi = (*user->LimitGrad)(flim);
cellPhi[i] = PetscMin(cellPhi[i],phi);
}
}
/* Apply limiter to gradient */
for (i=0; i<dof; i++) Scale2(cellPhi[i],&cgrad[i*DIM],&cgrad[i*DIM]);
ierr = PetscFree(cellPhi);CHKERRQ(ierr);
ierr = VecRestoreArray(Grad,&grad);CHKERRQ(ierr);
}
ierr = DMGetLocalVector(dmGrad,&locGradLimiter);CHKERRQ(ierr);
ierr = DMGlobalToLocalBegin(dmGrad,Grad,INSERT_VALUES,locGradLimiter);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(dmGrad,Grad,INSERT_VALUES,locGradLimiter);CHKERRQ(ierr);
ierr = VecCopy(TempVec, Grad);CHKERRQ(ierr);/*Restore the vector*/
ierr = DMGetLocalVector(dmGrad,&locGrad);CHKERRQ(ierr);
ierr = DMGlobalToLocalBegin(dmGrad,Grad,INSERT_VALUES,locGrad);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(dmGrad,Grad,INSERT_VALUES,locGrad);CHKERRQ(ierr);
ierr = DMRestoreGlobalVector(dmGrad,&Grad);CHKERRQ(ierr);
ierr = VecDestroy(&TempVec);CHKERRQ(ierr);
{
//.........这里部分代码省略.........
示例9: SetupJacobian
PetscErrorCode SetupJacobian(DM dm, Vec X, Mat jac, Mat B, void *ctx)
{
User user = (User) ctx;
Physics phys = user->model->physics;
PetscSection section, globalSection;
PetscInt cStart, cEnd, c;
// PetscInt numCells;
PetscInt dof = phys->dof;
PetscErrorCode ierr;
Vec inLocal;
PetscFunctionBegin;
PetscPrintf(PETSC_COMM_WORLD, "dof = %d\n", dof);
ierr = DMGetLocalVector(user->dm, &inLocal);CHKERRQ(ierr);
ierr = DMGlobalToLocalBegin(user->dm, X, INSERT_VALUES, inLocal);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(user->dm, X, INSERT_VALUES, inLocal);CHKERRQ(ierr);
ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr);
ierr = DMGetDefaultGlobalSection(dm, &globalSection);CHKERRQ(ierr);
ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr);
cEnd = user->cEndInterior;
//numCells = cEnd - cStart;
{
PetscInt NumOfIndices;
PetscInt indices[dof];
PetscScalar *values;
for (c = cStart; c < cEnd; ++c) {
ierr = DMPlexGetIndex(dm, section, globalSection, c, &NumOfIndices, indices);CHKERRQ(ierr);
ierr = PetscMalloc1(NumOfIndices*NumOfIndices, &values);CHKERRQ(ierr);
ierr = PetscMemzero(values, NumOfIndices*NumOfIndices* sizeof(PetscScalar));CHKERRQ(ierr);
if (user->second_order){
ierr = ComputeJacobian_LS(dm, inLocal, c, values, user);CHKERRQ(ierr);
}else{
ierr = ComputeJacobian_Upwind(dm, inLocal, c, values, user);CHKERRQ(ierr);
}
ierr = MatSetValues(jac, NumOfIndices, indices, NumOfIndices, indices, values, INSERT_VALUES);
ierr = PetscFree(values);CHKERRQ(ierr);
}
}
ierr = DMLocalToGlobalBegin(user->dm, inLocal, INSERT_VALUES, X);CHKERRQ(ierr);
ierr = DMLocalToGlobalEnd(user->dm, inLocal, INSERT_VALUES, X);CHKERRQ(ierr);
ierr = DMRestoreLocalVector(user->dm, &inLocal);CHKERRQ(ierr);
ierr = MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
{
PetscViewer viewer;
char filename[256];
sprintf(filename,"matJac.m");
ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,filename,
&viewer);CHKERRQ(ierr);
ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_DEFAULT);CHKERRQ(ierr);
ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
ierr = PetscViewerASCIIPrintf(viewer, "\n% -----------------------------\n");CHKERRQ(ierr);
ierr = PetscViewerASCIIPrintf(viewer, "% Matrix Jacobian: \n% -------------------------\n");CHKERRQ(ierr);
ierr = MatView(jac, viewer);CHKERRQ(ierr);
ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
示例10: main
int main(int argc,char **argv)
{
PetscErrorCode ierr;
DM dm;
Vec vec,vecLocal1,vecLocal2;
PetscScalar *a,***a1,***a2,expected;
PetscInt startx,starty,nx,ny,i,j,d,is,js,dof0,dof1,dof2,dofTotal,stencilWidth,Nx,Ny;
DMBoundaryType boundaryTypex,boundaryTypey;
PetscMPIInt rank;
ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
dof0 = 1;
dof1 = 1;
dof2 = 1;
stencilWidth = 2;
ierr = DMStagCreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_PERIODIC,DM_BOUNDARY_PERIODIC,4,4,PETSC_DECIDE,PETSC_DECIDE,dof0,dof1,dof2,DMSTAG_STENCIL_BOX,stencilWidth,NULL,NULL,&dm);CHKERRQ(ierr);
ierr = DMSetFromOptions(dm);CHKERRQ(ierr);
ierr = DMSetUp(dm);CHKERRQ(ierr);
ierr = DMStagGetDOF(dm,&dof0,&dof1,&dof2,NULL);CHKERRQ(ierr);
dofTotal = dof0 + 2*dof1 + dof2;
ierr = DMStagGetStencilWidth(dm,&stencilWidth);CHKERRQ(ierr);
ierr = DMCreateLocalVector(dm,&vecLocal1);CHKERRQ(ierr);
ierr = VecDuplicate(vecLocal1,&vecLocal2);CHKERRQ(ierr);
ierr = DMCreateGlobalVector(dm,&vec);CHKERRQ(ierr);
ierr = VecSet(vec,1.0);CHKERRQ(ierr);
ierr = VecSet(vecLocal1,0.0);CHKERRQ(ierr);
ierr = DMGlobalToLocalBegin(dm,vec,INSERT_VALUES,vecLocal1);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(dm,vec,INSERT_VALUES,vecLocal1);CHKERRQ(ierr);
ierr = DMStagGetCorners(dm,&startx,&starty,NULL,&nx,&ny,NULL,NULL,NULL,NULL);CHKERRQ(ierr);
ierr = DMStagVecGetArrayDOFRead(dm,vecLocal1,&a1);CHKERRQ(ierr);
ierr = DMStagVecGetArrayDOF(dm,vecLocal2,&a2);CHKERRQ(ierr);
for (j=starty; j<starty + ny; ++j) {
for (i=startx; i<startx + nx; ++i) {
for (d=0; d<dofTotal; ++d) {
if (a1[j][i][d] != 1.0) {
PetscPrintf(PETSC_COMM_SELF,"[%d] Unexpected value %g (expecting %g)\n",rank,a1[j][i][d],1.0);CHKERRQ(ierr);
}
a2[j][i][d] = 0.0;
for (js = -stencilWidth; js <= stencilWidth; ++js) {
for (is = -stencilWidth; is <= stencilWidth; ++is) {
a2[j][i][d] += a1[j+js][i+is][d];
}
}
}
}
}
ierr = DMStagVecRestoreArrayDOFRead(dm,vecLocal1,&a1);CHKERRQ(ierr);
ierr = DMStagVecRestoreArrayDOF(dm,vecLocal2,&a2);CHKERRQ(ierr);
DMLocalToGlobalBegin(dm,vecLocal2,INSERT_VALUES,vec);CHKERRQ(ierr);
DMLocalToGlobalEnd(dm,vecLocal2,INSERT_VALUES,vec);CHKERRQ(ierr);
/* For the all-periodic case, all values are the same . Otherwise, just check the local version */
ierr = DMStagGetBoundaryTypes(dm,&boundaryTypex,&boundaryTypey,NULL);CHKERRQ(ierr);
if (boundaryTypex == DM_BOUNDARY_PERIODIC && boundaryTypey == DM_BOUNDARY_PERIODIC) {
ierr = VecGetArray(vec,&a);CHKERRQ(ierr);
expected = 1.0; for(d=0;d<2;++d) expected *= (2*stencilWidth+1);
for (i=0; i<ny*nx*dofTotal; ++i) {
if (a[i] != expected) {
ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] Unexpected value %g (expecting %g)\n",rank,a[i],expected);CHKERRQ(ierr);
}
}
ierr = VecRestoreArray(vec,&a);CHKERRQ(ierr);
} else {
ierr = DMStagVecGetArrayDOFRead(dm,vecLocal2,&a2);CHKERRQ(ierr);
ierr = DMStagGetGlobalSizes(dm,&Nx,&Ny,NULL);CHKERRQ(ierr);
if (stencilWidth > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Non-periodic check implemented assuming stencilWidth = 1");
for (j=starty; j<starty + ny; ++j) {
for (i=startx; i<startx + nx; ++i) {
PetscInt dd,extra[2];
PetscBool bnd[2];
bnd[0] = (PetscBool)((i == 0 || i == Nx-1) && boundaryTypex != DM_BOUNDARY_PERIODIC);
bnd[1] = (PetscBool)((j == 0 || j == Ny-1) && boundaryTypey != DM_BOUNDARY_PERIODIC);
extra[0] = i == Nx-1 && boundaryTypex != DM_BOUNDARY_PERIODIC ? 1 : 0;
extra[1] = j == Ny-1 && boundaryTypey != DM_BOUNDARY_PERIODIC ? 1 : 0;
{ /* vertices */
PetscScalar expected = 1.0;
for (dd=0;dd<2;++dd) expected *= (bnd[dd] ? stencilWidth + 1 + extra[dd] : 2*stencilWidth + 1);
for (d=0; d<dof0; ++d) {
if (a2[j][i][d] != expected) {
ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] Element (%D,%D)[%D] Unexpected value %g (expecting %g)\n",rank,i,j,d,a2[j][i][d],expected);CHKERRQ(ierr);
}
}
}
{ /* down edges */
PetscScalar expected = (bnd[1] ? stencilWidth + 1 + extra[1] : 2*stencilWidth + 1);
expected *= ((bnd[0] ? 1 : 2) * stencilWidth + 1);
for (d=dof0; d<dof0+dof1; ++d) {
if (a2[j][i][d] != expected) {
ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] Element (%D,%D)[%D] Unexpected value %g (expecting %g)\n",rank,i,j,d,a2[j][i][d],expected);CHKERRQ(ierr);
}
}
}
{ /* left edges */
PetscScalar expected = (bnd[0] ? stencilWidth + 1 + extra[0] : 2*stencilWidth + 1);
expected *= ((bnd[1] ? 1 : 2) * stencilWidth + 1);
//.........这里部分代码省略.........
示例11: SNESSetJacobian
/*
FormJacobian - Evaluates Jacobian matrix.
Input Parameters:
. snes - SNES context
. X - input vector
. ptr - optional user-defined context, as set by SNESSetJacobian()
Output Parameters:
. tH - Jacobian matrix
*/
PetscErrorCode FormJacobian(SNES snes, Vec X, Mat H, Mat tHPre, void *ptr)
{
AppCtx *user;
PetscErrorCode ierr;
PetscInt i,j,k;
PetscInt mx, my;
MatStencil row,col[7];
PetscScalar hx, hy, hydhx, hxdhy;
PetscScalar f1,f2,f3,f4,f5,f6,d1,d2,d3,d4,d5,d6,d7,d8,xc,xl,xr,xt,xb,xlt,xrb;
PetscScalar hl,hr,ht,hb,hc,htl,hbr;
PetscScalar **x, v[7];
PetscBool assembled;
PetscInt xs,xm,ys,ym;
Vec localX;
DM da;
PetscFunctionBeginUser;
ierr = SNESGetDM(snes,&da);CHKERRQ(ierr);
ierr = SNESGetApplicationContext(snes,(void**)&user);CHKERRQ(ierr);
ierr = DMDAGetInfo(da,PETSC_IGNORE,&mx,&my,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr);
hx = 1.0/(mx+1); hy=1.0/(my+1); hydhx=hy/hx; hxdhy=hx/hy;
/* Set various matrix options */
ierr = MatAssembled(H,&assembled);CHKERRQ(ierr);
if (assembled) {ierr = MatZeroEntries(H);CHKERRQ(ierr);}
/* Get local vector */
ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr);
/* Get ghost points */
ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
/* Get pointers to vector data */
ierr = DMDAVecGetArray(da,localX, &x);CHKERRQ(ierr);
ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr);
/* Compute Jacobian 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 */
if (i==0) {
xl = user->left[j+1];
xlt = user->left[j+2];
} else xl = x[j][i-1];
/* Bottom */
if (j==0) {
xb =user->bottom[i+1];
xrb = user->bottom[i+2];
} else xb = x[j-1][i];
/* Right */
if (i+1 == mx) {
xr =user->right[j+1];
xrb = user->right[j];
} else xr = x[j][i+1];
/* Top */
if (j+1==my) {
xt =user->top[i+1];
xlt = user->top[i];
} else xt = x[j+1][i];
/* Top left */
if (i>0 && j+1<my) xlt = x[j+1][i-1];
/* Bottom right */
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 = PetscSqrtScalar(1.0 + d1*d1 + d7*d7);
f2 = PetscSqrtScalar(1.0 + d1*d1 + d4*d4);
f3 = PetscSqrtScalar(1.0 + d3*d3 + d8*d8);
f4 = PetscSqrtScalar(1.0 + d3*d3 + d2*d2);
f5 = PetscSqrtScalar(1.0 + d2*d2 + d5*d5);
f6 = PetscSqrtScalar(1.0 + d4*d4 + d6*d6);
//.........这里部分代码省略.........
示例12: SNESSetFunction
/* FormGradient - Evaluates gradient of f.
Input Parameters:
. snes - the SNES context
. X - input vector
. ptr - optional user-defined context, as set by SNESSetFunction()
Output Parameters:
. G - vector containing the newly evaluated gradient
*/
PetscErrorCode FormGradient(SNES snes, Vec X, Vec G, void *ptr)
{
AppCtx *user;
int ierr;
PetscInt i,j;
PetscInt mx, my;
PetscScalar hx,hy, hydhx, hxdhy;
PetscScalar f1,f2,f3,f4,f5,f6,d1,d2,d3,d4,d5,d6,d7,d8,xc,xl,xr,xt,xb,xlt,xrb;
PetscScalar df1dxc,df2dxc,df3dxc,df4dxc,df5dxc,df6dxc;
PetscScalar **g, **x;
PetscInt xs,xm,ys,ym;
Vec localX;
DM da;
PetscFunctionBeginUser;
ierr = SNESGetDM(snes,&da);CHKERRQ(ierr);
ierr = SNESGetApplicationContext(snes,(void**)&user);CHKERRQ(ierr);
ierr = DMDAGetInfo(da,PETSC_IGNORE,&mx,&my,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr);
hx = 1.0/(mx+1);hy=1.0/(my+1); hydhx=hy/hx; hxdhy=hx/hy;
ierr = VecSet(G,0.0);CHKERRQ(ierr);
/* Get local vector */
ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr);
/* Get ghost points */
ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr);
/* Get pointer to local vector data */
ierr = DMDAVecGetArray(da,localX, &x);CHKERRQ(ierr);
ierr = DMDAVecGetArray(da,G, &g);CHKERRQ(ierr);
ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr);
/* Compute function 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+1];
xlt = user->left[j+2];
} else xl = x[j][i-1];
if (j==0) { /* bottom side */
xb = user->bottom[i+1];
xrb = user->bottom[i+2];
} else xb = x[j-1][i];
if (i+1 == mx) { /* right side */
xr = user->right[j+1];
xrb = user->right[j];
} else xr = x[j][i+1];
if (j+1==0+my) { /* top side */
xt = user->top[i+1];
xlt = user->top[i];
} else xt = x[j+1][i];
if (i>0 && j+1<my) xlt = x[j+1][i-1]; /* left top side */
if (j>0 && i+1<mx) xrb = x[j-1][i+1]; /* right bottom */
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 /= hx;
d2 /= hx;
d3 /= hy;
d4 /= hy;
d5 /= hy;
d6 /= hx;
d7 /= hy;
d8 /= hx;
f1 = PetscSqrtScalar(1.0 + d1*d1 + d7*d7);
f2 = PetscSqrtScalar(1.0 + d1*d1 + d4*d4);
f3 = PetscSqrtScalar(1.0 + d3*d3 + d8*d8);
//.........这里部分代码省略.........
示例13: main
int main(int argc,char **argv)
{
PetscMPIInt rank;
PetscErrorCode ierr;
PetscInt M = 10,N = 8,m = PETSC_DECIDE;
PetscInt s =2,w=2,n = PETSC_DECIDE,nloc,l,i,j,kk;
PetscInt Xs,Xm,Ys,Ym,iloc,*iglobal;
const PetscInt *ltog;
PetscInt *lx = NULL,*ly = NULL;
PetscBool testorder = PETSC_FALSE,flg;
DMBoundaryType bx = DM_BOUNDARY_NONE,by= DM_BOUNDARY_NONE;
DM da;
PetscViewer viewer;
Vec local,global;
PetscScalar value;
DMDAStencilType st = DMDA_STENCIL_BOX;
AO ao;
ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",300,0,400,400,&viewer);CHKERRQ(ierr);
/* Readoptions */
ierr = PetscOptionsGetInt(NULL,NULL,"-NX",&M,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,NULL,"-NY",&N,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,NULL,"-s",&s,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,NULL,"-w",&w,NULL);CHKERRQ(ierr);
flg = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-xperiodic",&flg,NULL);CHKERRQ(ierr); if (flg) bx = DM_BOUNDARY_PERIODIC;
flg = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-yperiodic",&flg,NULL);CHKERRQ(ierr); if (flg) by = DM_BOUNDARY_PERIODIC;
flg = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-xghosted",&flg,NULL);CHKERRQ(ierr); if (flg) bx = DM_BOUNDARY_GHOSTED;
flg = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-yghosted",&flg,NULL);CHKERRQ(ierr); if (flg) by = DM_BOUNDARY_GHOSTED;
flg = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-star",&flg,NULL);CHKERRQ(ierr); if (flg) st = DMDA_STENCIL_STAR;
flg = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-box",&flg,NULL);CHKERRQ(ierr); if (flg) st = DMDA_STENCIL_BOX;
flg = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-testorder",&testorder,NULL);CHKERRQ(ierr);
/*
Test putting two nodes in x and y on each processor, exact last processor
in x and y gets the rest.
*/
flg = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-distribute",&flg,NULL);CHKERRQ(ierr);
if (flg) {
if (m == PETSC_DECIDE) SETERRQ(PETSC_COMM_WORLD,1,"Must set -m option with -distribute option");
ierr = PetscMalloc1(m,&lx);CHKERRQ(ierr);
for (i=0; i<m-1; i++) { lx[i] = 4;}
lx[m-1] = M - 4*(m-1);
if (n == PETSC_DECIDE) SETERRQ(PETSC_COMM_WORLD,1,"Must set -n option with -distribute option");
ierr = PetscMalloc1(n,&ly);CHKERRQ(ierr);
for (i=0; i<n-1; i++) { ly[i] = 2;}
ly[n-1] = N - 2*(n-1);
}
/* Create distributed array and get vectors */
ierr = DMDACreate2d(PETSC_COMM_WORLD,bx,by,st,M,N,m,n,w,s,lx,ly,&da);CHKERRQ(ierr);
ierr = PetscFree(lx);CHKERRQ(ierr);
ierr = PetscFree(ly);CHKERRQ(ierr);
ierr = DMView(da,viewer);CHKERRQ(ierr);
ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr);
ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr);
/* Set global vector; send ghost points to local vectors */
value = 1;
ierr = VecSet(global,value);CHKERRQ(ierr);
ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
/* Scale local vectors according to processor rank; pass to global vector */
ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
value = rank;
ierr = VecScale(local,value);CHKERRQ(ierr);
ierr = DMLocalToGlobalBegin(da,local,INSERT_VALUES,global);CHKERRQ(ierr);
ierr = DMLocalToGlobalEnd(da,local,INSERT_VALUES,global);CHKERRQ(ierr);
if (!testorder) { /* turn off printing when testing ordering mappings */
ierr = PetscPrintf(PETSC_COMM_WORLD,"\nGlobal Vectors:\n");CHKERRQ(ierr);
ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
ierr = PetscPrintf(PETSC_COMM_WORLD,"\n\n");CHKERRQ(ierr);
}
/* Send ghost points to local vectors */
ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
flg = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-local_print",&flg,NULL);CHKERRQ(ierr);
if (flg) {
PetscViewer sviewer;
ierr = PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,"\nLocal Vector: processor %d\n",rank);CHKERRQ(ierr);
//.........这里部分代码省略.........
示例14: F
/*
IFunction - Evaluates nonlinear function, F(U).
Input Parameters:
. ts - the TS context
. U - input vector
. ptr - optional user-defined context, as set by SNESSetFunction()
Output Parameter:
. F - function vector
*/
PetscErrorCode IFunction(TS ts,PetscReal ftime,Vec U,Vec Udot,Vec F,void *ptr)
{
DM da;
PetscErrorCode ierr;
PetscInt i,c,Mx,xs,xm,N;
PetscReal hx,sx,x;
PetscScalar uxx;
PetscScalar **u,**f,**udot;
Vec localU;
PetscFunctionBegin;
ierr = TSGetDM(ts,&da);CHKERRQ(ierr);
ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr);
ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,&N,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr);
hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx);
/*
Scatter ghost points to local vector,using the 2-step process
DMGlobalToLocalBegin(),DMGlobalToLocalEnd().
By placing code between these two statements, computations can be
done while messages are in transition.
*/
ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr);
/*
Get pointers to vector data
*/
ierr = DMDAVecGetArrayDOF(da,localU,&u);CHKERRQ(ierr);
ierr = DMDAVecGetArrayDOF(da,Udot,&udot);CHKERRQ(ierr);
ierr = DMDAVecGetArrayDOF(da,F,&f);CHKERRQ(ierr);
/*
Get local grid boundaries
*/
ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr);
/*
Compute function over the locally owned part of the grid
*/
for (i=xs; i<xs+xm; i++) {
x = i*hx;
/* diffusion term */
for (c=0; c<N; c++) {
uxx = (-2.0*u[i][c] + u[i-1][c] + u[i+1][c])*sx;
f[i][c] = udot[i][c] - uxx;
}
/* reaction terms */
for (c=0; c<N/3; c++) {
f[i][c] += 500*u[i][c]*u[i][c] + 500*u[i][c]*u[i][c+1];
f[i][c+1] += -500*u[i][c]*u[i][c] + 500*u[i][c]*u[i][c+1];
f[i][c+2] -= 500*u[i][c]*u[i][c+1];
}
/* forcing term */
f[i][0] -= 5*PetscExpScalar((1.0 - x)*(1.0 - x));
}
/*
Restore vectors
*/
ierr = DMDAVecRestoreArrayDOF(da,localU,&u);CHKERRQ(ierr);
ierr = DMDAVecRestoreArrayDOF(da,Udot,&udot);CHKERRQ(ierr);
ierr = DMDAVecRestoreArrayDOF(da,F,&f);CHKERRQ(ierr);
ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例15: main
int main(int argc,char **argv)
{
PetscMPIInt rank;
PetscInt M = 13,s=1,dof=1;
DMDABoundaryType bx = DMDA_BOUNDARY_PERIODIC;
PetscErrorCode ierr;
DM da;
PetscViewer viewer;
Vec local,global;
PetscScalar value;
PetscDraw draw;
PetscBool flg = PETSC_FALSE;
ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr);
/* Create viewers */
ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",280,480,600,200,&viewer);CHKERRQ(ierr);
ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr);
/* Readoptions */
ierr = PetscOptionsGetInt(NULL,"-M",&M,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetEnum(NULL,"-wrap",DMDABoundaryTypes,(PetscEnum*)&bx,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,"-dof",&dof,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,"-s",&s,NULL);CHKERRQ(ierr);
/* Create distributed array and get vectors */
ierr = DMDACreate1d(PETSC_COMM_WORLD,bx,M,dof,s,NULL,&da);CHKERRQ(ierr);
ierr = DMView(da,viewer);CHKERRQ(ierr);
ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr);
ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr);
/* Set global vector; send ghost points to local vectors */
value = 1;
ierr = VecSet(global,value);CHKERRQ(ierr);
ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
/* Scale local vectors according to processor rank; pass to global vector */
ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
value = rank+1;
ierr = VecScale(local,value);CHKERRQ(ierr);
ierr = DMLocalToGlobalBegin(da,local,INSERT_VALUES,global);CHKERRQ(ierr);
ierr = DMLocalToGlobalEnd(da,local,INSERT_VALUES,global);CHKERRQ(ierr);
ierr = VecView(global,viewer);CHKERRQ(ierr);
ierr = PetscPrintf(PETSC_COMM_WORLD,"\nGlobal Vector:\n");CHKERRQ(ierr);
ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
ierr = PetscPrintf(PETSC_COMM_WORLD,"\n");CHKERRQ(ierr);
/* Send ghost points to local vectors */
ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr);
ierr = PetscOptionsGetBool(NULL,"-local_print",&flg,NULL);CHKERRQ(ierr);
if (flg) {
PetscViewer sviewer;
ISLocalToGlobalMapping is;
ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD,PETSC_TRUE);CHKERRQ(ierr);
ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,"\nLocal Vector: processor %d\n",rank);CHKERRQ(ierr);
ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr);
ierr = VecView(local,sviewer);CHKERRQ(ierr);
ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr);
ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD,PETSC_STDOUT);CHKERRQ(ierr);
ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,"\nLocal to global mapping: processor %d\n",rank);CHKERRQ(ierr);
ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr);
ierr = DMGetLocalToGlobalMapping(da,&is);CHKERRQ(ierr);
ierr = ISLocalToGlobalMappingView(is,sviewer);CHKERRQ(ierr);
ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr);
ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD,PETSC_STDOUT);CHKERRQ(ierr);
}
/* Free memory */
ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
ierr = VecDestroy(&global);CHKERRQ(ierr);
ierr = VecDestroy(&local);CHKERRQ(ierr);
ierr = DMDestroy(&da);CHKERRQ(ierr);
ierr = PetscFinalize();
return 0;
}