PetscErrorCode ExactSolution(DM packer,Vec U) { PF pf; Vec x,u_global; PetscScalar *w; DM da; PetscErrorCode ierr; PetscInt m; PetscFunctionBeginUser; ierr = DMCompositeGetEntries(packer,&m,&da);CHKERRQ(ierr); ierr = PFCreate(PETSC_COMM_WORLD,1,2,&pf);CHKERRQ(ierr); /* The cast through PETSC_UINTPTR_T is so that compilers will warn about casting to void * from void(*)(void) */ ierr = PFSetType(pf,PFQUICK,(void*)(PETSC_UINTPTR_T)u_solution);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&x);CHKERRQ(ierr); if (!x) { ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&x);CHKERRQ(ierr); } ierr = DMCompositeGetAccess(packer,U,&w,&u_global,0);CHKERRQ(ierr); if (w) w[0] = .25; ierr = PFApplyVec(pf,x,u_global);CHKERRQ(ierr); ierr = PFDestroy(&pf);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(packer,U,&w,&u_global,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode OpSolution(Op op,DM dm,Vec U) { PetscErrorCode ierr; Vec X; const PetscScalar *x; PetscScalar *u; PetscReal L[3]; PetscInt i,m,bs; PetscFunctionBegin; ierr = PetscLogEventBegin(OP_Solution,dm,U,0,0);CHKERRQ(ierr); ierr = DMGetCoordinates(dm,&X);CHKERRQ(ierr); ierr = VecStrideMax(X,0,NULL,&L[0]);CHKERRQ(ierr); ierr = VecStrideMax(X,1,NULL,&L[1]);CHKERRQ(ierr); ierr = VecStrideMax(X,2,NULL,&L[2]);CHKERRQ(ierr); ierr = VecGetLocalSize(U,&m);CHKERRQ(ierr); ierr = VecGetBlockSize(U,&bs);CHKERRQ(ierr); ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); ierr = VecGetArray(U,&u);CHKERRQ(ierr); for (i=0; i<m/bs; i++) { ierr = (op->PointwiseSolution)(op,&x[i*3],L,&u[i*bs]);CHKERRQ(ierr); } ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); ierr = PetscLogEventEnd(OP_Solution,dm,U,0,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Compute the values of the surface mass balance and ice hardness. */ PetscErrorCode FillDistributedParams(ExactCtx *exact, AppCtx *user) { PetscErrorCode ierr; PetscInt i; PetscReal dum1, dum2, *xstag, *Mstag, *Bstag; DM coord_da; Vec coord_x; PetscFunctionBegin; ierr = DMGetCoordinateDM(user->stagda, &coord_da); CHKERRQ(ierr); ierr = DMGetCoordinates(user->stagda, &coord_x); CHKERRQ(ierr); ierr = DMDAVecGetArray(coord_da,coord_x,&xstag);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->stagda,user->Mstag,&Mstag);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->stagda,user->Bstag,&Bstag);CHKERRQ(ierr); for (i = user->xs; i < user->xs + user->xm - 1; i++) { /* note "-1" at end */ if (xstag[i] < exact->xg) { ierr = exactBod(xstag[i], &dum1, &dum2, &(Mstag[i])); CHKERRQ(ierr); ierr = exactBodBueler(xstag[i], &dum1, &(Bstag[i])); CHKERRQ(ierr); } else { Mstag[i] = exact->Mg; Bstag[i] = exact->Bg; } } ierr = DMDAVecRestoreArray(coord_da,coord_x,&xstag);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->stagda,user->Mstag,&Mstag);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->stagda,user->Bstag,&Bstag);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Put a not-unreasonable initial guess in Hu. */ PetscErrorCode FillInitial(AppCtx *user, Vec *vHu) { PetscErrorCode ierr; PetscInt i; PetscReal *x; Node *Hu; const PetscReal Hcguess = 300.0, ucguess = (300.0/user->secpera), Hslope = (Hcguess - user->Ha) / (user->xc - user->xa), uslope = (ucguess - user->ua) / (user->xc - user->xa); DM coord_da; Vec coord_x; PetscFunctionBegin; ierr = DMGetCoordinateDM(user->da, &coord_da); CHKERRQ(ierr); ierr = DMGetCoordinates(user->da, &coord_x); CHKERRQ(ierr); ierr = DMDAVecGetArray(coord_da,coord_x,&x);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->da,*vHu,&Hu);CHKERRQ(ierr); for (i = user->xs; i < user->xs + user->xm; i++) { /* use linear function which uses upstream Dirichlet b.c. but guesses at calving-front values */ Hu[i].H = user->Ha + Hslope * (x[i] - user->xa); Hu[i].u = user->ua + uslope * (x[i] - user->xa); } ierr = DMDAVecRestoreArray(coord_da,coord_x,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->da,*vHu,&Hu);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DADefineXLinearField2D(DM da,Vec field) { PetscErrorCode ierr; PetscInt i,j; PetscInt sx,nx,sy,ny; Vec Gcoords; DMDACoor2d **XX; PetscScalar **FF; DM cda; PetscFunctionBeginUser; ierr = DMGetCoordinateDM(da,&cda);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&Gcoords);CHKERRQ(ierr); ierr = DMDAVecGetArray(cda,Gcoords,&XX);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,field,&FF);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&sx,&sy,0,&nx,&ny,0);CHKERRQ(ierr); for (i=sx; i<sx+nx; i++) { for (j=sy; j<sy+ny; j++ ) { FF[j][i] = 10.0 + 3.0 * XX[j][i].x + 5.5 * XX[j][i].y + 8.003 * XX[j][i].x * XX[j][i].y; } } ierr = DMDAVecRestoreArray(da,field,&FF);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(cda,Gcoords,&XX);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode SetCoordinates1d(DM da) { PetscErrorCode ierr; PetscInt i,start,m; Vec gc,global; PetscScalar *coors; DM cda; PetscFunctionBeginUser; ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da,&cda);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(da,&gc);CHKERRQ(ierr); ierr = DMDAVecGetArray(cda,gc,&coors);CHKERRQ(ierr); ierr = DMDAGetCorners(cda,&start,0,0,&m,0,0);CHKERRQ(ierr); for (i=start; i<start+m; i++) { if (i % 2) { coors[i] = coors[i-1] + .1*(coors[i+1] - coors[i-1]); } } ierr = DMDAVecRestoreArray(cda,gc,&coors);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&global);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(cda,gc,INSERT_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(cda,gc,INSERT_VALUES,global);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode SetCoordinates2d(DM da) { PetscErrorCode ierr; PetscInt i,j,mstart,m,nstart,n; Vec local,global; DMDACoor2d **coors,**coorslocal; DM cda; PetscFunctionBeginUser; ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da,&cda);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&global);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(da,&local);CHKERRQ(ierr); ierr = DMDAVecGetArray(cda,global,&coors);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(cda,local,&coorslocal);CHKERRQ(ierr); ierr = DMDAGetCorners(cda,&mstart,&nstart,0,&m,&n,0);CHKERRQ(ierr); for (i=mstart; i<mstart+m; i++) { for (j=nstart; j<nstart+n; j++) { if (i % 2) { coors[j][i].x = coorslocal[j][i-1].x + .1*(coorslocal[j][i+1].x - coorslocal[j][i-1].x); } if (j % 2) { coors[j][i].y = coorslocal[j-1][i].y + .3*(coorslocal[j+1][i].y - coorslocal[j-1][i].y); } } } ierr = DMDAVecRestoreArray(cda,global,&coors);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayRead(cda,local,&coorslocal);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(cda,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(cda,global,INSERT_VALUES,local);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode SetCoordinates3d(DM da) { PetscErrorCode ierr; PetscInt i,j,mstart,m,nstart,n,pstart,p,k; Vec gc,global; DMDACoor3d ***coors; DM cda; PetscFunctionBeginUser; ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da,&cda);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(da,&gc);CHKERRQ(ierr); ierr = DMDAVecGetArray(cda,gc,&coors);CHKERRQ(ierr); ierr = DMDAGetCorners(cda,&mstart,&nstart,&pstart,&m,&n,&p);CHKERRQ(ierr); for (i=mstart; i<mstart+m; i++) { for (j=nstart; j<nstart+n; j++) { for (k=pstart; k<pstart+p; k++) { if (i % 2) { coors[k][j][i].x = coors[k][j][i-1].x + .1*(coors[k][j][i+1].x - coors[k][j][i-1].x); } if (j % 2) { coors[k][j][i].y = coors[k][j-1][i].y + .3*(coors[k][j+1][i].y - coors[k][j-1][i].y); } if (k % 2) { coors[k][j][i].z = coors[k-1][j][i].z + .4*(coors[k+1][j][i].z - coors[k-1][j][i].z); } } } } ierr = DMDAVecRestoreArray(cda,gc,&coors);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&global);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(cda,gc,INSERT_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(cda,gc,INSERT_VALUES,global);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode FormPsiAndInitialGuess(DM da,Vec U0,PetscBool feasible) { ObsCtx *user; PetscErrorCode ierr; PetscInt i,j,Mx,My,xs,ys,xm,ym; DM coordDA; Vec coordinates; DMDACoor2d **coords; PetscReal **psi, **u0, **uexact, x, y, r, afree = 0.69797, A = 0.68026, B = 0.47152, pi = 3.1415926; PetscFunctionBeginUser; ierr = DMGetApplicationContext(da,&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); ierr = DMDAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da, &coordDA);CHKERRQ(ierr); ierr = DMGetCoordinates(da, &coordinates);CHKERRQ(ierr); ierr = DMDAVecGetArray(coordDA, coordinates, &coords);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, user->psi, &psi);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, U0, &u0);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, user->uexact, &uexact);CHKERRQ(ierr); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { x = coords[j][i].x; y = coords[j][i].y; r = sqrt(x * x + y * y); if (r <= 1.0) { psi[j][i] = sqrt(1.0 - r * r); } else { psi[j][i] = -1.0; } if (r <= afree) { uexact[j][i] = psi[j][i]; /* on the obstacle */ } else { uexact[j][i] = - A * log(r) + B; /* solves the laplace eqn */ } if (feasible) { if (i == 0 || j == 0 || i == Mx-1 || j == My-1) { u0[j][i] = uexact[j][i]; } else { /* initial guess is admissible: it is above the obstacle */ u0[j][i] = uexact[j][i] + cos(pi * x / 4) * cos(pi * y / 4); } } else { u0[j][i] = 0.; } } } ierr = DMDAVecRestoreArray(da, user->psi, &psi);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da, U0, &u0);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da, user->uexact, &uexact);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(coordDA, coordinates, &coords);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Compute the exact thickness and velocity on the regular grid, and the staggered-grid ice hardness, over the locally-owned part of the grid. */ PetscErrorCode FillExactSoln(ExactCtx *exact, AppCtx *user) { PetscErrorCode ierr; PetscInt i; PetscReal dum1, *x; Node *Hu; DM coord_da; Vec coord_x; PetscFunctionBegin; ierr = DMGetCoordinateDM(user->da, &coord_da); CHKERRQ(ierr); ierr = DMGetCoordinates(user->da, &coord_x); CHKERRQ(ierr); ierr = DMDAVecGetArray(coord_da,coord_x,&x);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->da,exact->Hu,&Hu);CHKERRQ(ierr); for (i = user->xs; i < user->xs + user->xm; i++) { if (x[i] < exact->xg) { /* grounded part: Bodvardsson formula */ ierr = exactBod(x[i], &(Hu[i].H), &(Hu[i].u), &dum1); CHKERRQ(ierr); } else { /* floating part: van der Veen formula */ ierr = exactVeen(x[i], exact->Mg, &(Hu[i].H), &(Hu[i].u)); if (ierr) PetscPrintf(PETSC_COMM_WORLD,"WARNING: exactVeen() returns error %d at i=%d, x[i]=%.3f km\n", ierr,i,x[i]/1000.0); } } ierr = DMDAVecRestoreArray(coord_da,coord_x,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->da,exact->Hu,&Hu);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode FormPsiAndExactSoln(DM da) { ObsCtx *user; PetscErrorCode ierr; DMDALocalInfo info; PetscInt i,j; DM coordDA; Vec coordinates; DMDACoor2d **coords; PetscReal **psi, **uexact, r; const PetscReal afree = 0.69797, A = 0.68026, B = 0.47152; PetscFunctionBeginUser; ierr = DMGetApplicationContext(da,&user);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da,&info); CHKERRQ(ierr); ierr = DMGetCoordinateDM(da, &coordDA);CHKERRQ(ierr); ierr = DMGetCoordinates(da, &coordinates);CHKERRQ(ierr); ierr = DMDAVecGetArray(coordDA, coordinates, &coords);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, user->psi, &psi);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, user->uexact, &uexact);CHKERRQ(ierr); for (j=info.ys; j<info.ys+info.ym; j++) { for (i=info.xs; i<info.xs+info.xm; i++) { r = PetscSqrtReal(pow(coords[j][i].x,2) + pow(coords[j][i].y,2)); if (r <= 1.0) psi[j][i] = PetscSqrtReal(1.0 - r * r); else psi[j][i] = -1.0; if (r <= afree) uexact[j][i] = psi[j][i]; /* on the obstacle */ else uexact[j][i] = - A * PetscLogReal(r) + B; /* solves the laplace eqn */ } } ierr = DMDAVecRestoreArray(da, user->psi, &psi);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da, user->uexact, &uexact);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(coordDA, coordinates, &coords);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ini_bou(Vec X,AppCtx* user) { PetscErrorCode ierr; DM cda; DMDACoor2d **coors; PetscScalar **p; Vec gc; PetscInt M,N,I,J; PetscMPIInt rank; PetscFunctionBeginUser; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = DMDAGetInfo(user->da,NULL,&M,&N,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); user->dx = (user->xmax - user->xmin)/(M-1); user->dy = (user->ymax - user->ymin)/(N-1); ierr = DMGetCoordinateDM(user->da,&cda);CHKERRQ(ierr); ierr = DMGetCoordinates(user->da,&gc);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(cda,gc,&coors);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->da,X,&p);CHKERRQ(ierr); /* Point mass at (mux,muy) */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Original user->mux = %f, user->muy = %f\n",user->mux,user->muy);CHKERRQ(ierr); ierr = DMDAGetLogicalCoordinate(user->da,user->mux,user->muy,0.0,&I,&J,NULL,&user->mux,&user->muy,NULL);CHKERRQ(ierr); user->PM_min = user->Pmax*PetscSinScalar(user->mux); ierr = PetscPrintf(PETSC_COMM_WORLD,"Corrected user->mux = %f, user->muy = %f user->PM_min = %f,user->dx = %f\n",user->mux,user->muy,user->PM_min,user->dx);CHKERRQ(ierr); if (I > -1 && J > -1) { p[J][I] = 1.0; } ierr = DMDAVecRestoreArrayRead(cda,gc,&coors);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->da,X,&p);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* FormExactSolution2 - Forms initial approximation. Input Parameters: da - The DM user - user-defined application context Output Parameter: X - vector */ PetscErrorCode FormExactSolution2(DM da, AppCtx *user, Vec U) { DM coordDA; Vec coordinates; DMDACoor2d **coords; PetscScalar **u; PetscReal x, y; PetscInt xs, ys, xm, ym, i, j; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = DMDAGetCorners(da, &xs, &ys, NULL, &xm, &ym, NULL);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da, &coordDA);CHKERRQ(ierr); ierr = DMGetCoordinates(da, &coordinates);CHKERRQ(ierr); ierr = DMDAVecGetArray(coordDA, coordinates, &coords);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, U, &u);CHKERRQ(ierr); for (j = ys; j < ys+ym; ++j) { for (i = xs; i < xs+xm; ++i) { x = PetscRealPart(coords[j][i].x); y = PetscRealPart(coords[j][i].y); u[j][i] = PetscSinReal(PETSC_PI*x)*PetscSinReal(PETSC_PI*y); } } ierr = DMDAVecRestoreArray(da, U, &u);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(coordDA, coordinates, &coords);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ DMPlexClone - Creates a DMPlex object with the same mesh as the original. Collective on MPI_Comm Input Parameter: . dm - The original DMPlex object Output Parameter: . newdm - The new DMPlex object Level: beginner .keywords: DMPlex, create @*/ PetscErrorCode DMPlexClone(DM dm, DM *newdm) { DM_Plex *mesh; Vec coords; void *ctx; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(dm, DM_CLASSID, 1); PetscValidPointer(newdm,2); ierr = DMCreate(PetscObjectComm((PetscObject)dm), newdm);CHKERRQ(ierr); ierr = PetscSFDestroy(&(*newdm)->sf);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject) dm->sf);CHKERRQ(ierr); (*newdm)->sf = dm->sf; mesh = (DM_Plex*) dm->data; mesh->refct++; (*newdm)->data = mesh; ierr = PetscObjectChangeTypeName((PetscObject) *newdm, DMPLEX);CHKERRQ(ierr); ierr = DMInitialize_Plex(*newdm);CHKERRQ(ierr); ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr); ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr); if (coords) { ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr); } else { ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);} } PetscFunctionReturn(0); }
PetscErrorCode ini_bou(Vec X,AppCtx* user) { PetscErrorCode ierr; DM cda; DMDACoor2d **coors; PetscScalar **p; Vec gc; PetscInt i,j; PetscInt xs,ys,xm,ym,M,N; PetscScalar xi,yi; PetscScalar sigmax=user->sigmax,sigmay=user->sigmay; PetscScalar rho =user->rho; PetscScalar mux =user->mux,muy=user->muy; PetscMPIInt rank; PetscScalar sum; PetscFunctionBeginUser; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = DMDAGetInfo(user->da,NULL,&M,&N,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); user->dx = (user->xmax - user->xmin)/(M-1); user->dy = (user->ymax - user->ymin)/(N-1); ierr = DMGetCoordinateDM(user->da,&cda);CHKERRQ(ierr); ierr = DMGetCoordinates(user->da,&gc);CHKERRQ(ierr); ierr = DMDAVecGetArray(cda,gc,&coors);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->da,X,&p);CHKERRQ(ierr); ierr = DMDAGetCorners(cda,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr); /* mux and muy need to be grid points in the x and y-direction otherwise the solution goes unstable muy is set by choosing the y domain, no. of grid points along y-direction so that muy is a grid point in the y-direction. We only modify mux here */ mux = user->mux = coors[0][M/2+10].x; /* For -pi < x < pi, this should be some angle between 0 and pi/2 */ if (user->nonoiseinitial) { for (i=xs; i < xs+xm; i++) { for (j=ys; j < ys+ym; j++) { xi = coors[j][i].x; yi = coors[j][i].y; if ((xi == mux) && (yi == muy)) { p[j][i] = 1.0; } } } } else { /* Change PM_min accordingly */ user->PM_min = user->Pmax*sin(mux); for (i=xs; i < xs+xm; i++) { for (j=ys; j < ys+ym; j++) { xi = coors[j][i].x; yi = coors[j][i].y; p[j][i] = (0.5/(PETSC_PI*sigmax*sigmay*PetscSqrtScalar(1.0-rho*rho)))*PetscExpScalar(-0.5/(1-rho*rho)*(PetscPowScalar((xi-mux)/sigmax,2) + PetscPowScalar((yi-muy)/sigmay,2) - 2*rho*(xi-mux)*(yi-muy)/(sigmax*sigmay))); } } } ierr = DMDAVecRestoreArray(cda,gc,&coors);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->da,X,&p);CHKERRQ(ierr); ierr = VecSum(X,&sum);CHKERRQ(ierr); ierr = VecScale(X,1.0/sum);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DAApplyTrilinearMapping(DM da) { PetscErrorCode ierr; PetscInt i,j,k; PetscInt sx,nx,sy,ny,sz,nz; Vec Gcoords; DMDACoor3d ***XX; PetscScalar xx,yy,zz; DM cda; PetscFunctionBeginUser; ierr = DMDASetUniformCoordinates(da, -1.0,1.0, -1.0,1.0, -1.0,1.0 );CHKERRQ(ierr); ierr = DMGetCoordinateDM(da,&cda);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&Gcoords);CHKERRQ(ierr); ierr = DMDAVecGetArray(cda,Gcoords,&XX);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&sx,&sy,&sz,&nx,&ny,&nz);CHKERRQ(ierr); for (i=sx; i<sx+nx; i++) { for (j=sy; j<sy+ny; j++ ) { for (k=sz; k<sz+nz; k++ ) { PetscScalar Ni[8]; PetscScalar xi = XX[k][j][i].x; PetscScalar eta = XX[k][j][i].y; PetscScalar zeta = XX[k][j][i].z; PetscScalar xn[] = {0.0,2.0,0.2,3.5, 0.0,2.1,0.23,3.125 }; PetscScalar yn[] = {-1.3,0.0,2.0,4.0, -1.45,-0.1,2.24,3.79 }; PetscScalar zn[] = {0.0,0.3,-0.1,0.123, 0.956,1.32,1.12,0.798 }; PetscInt p; Ni[0] = 0.125*(1.0-xi)*(1.0-eta)*(1.0-zeta); Ni[1] = 0.125*(1.0+xi)*(1.0-eta)*(1.0-zeta); Ni[2] = 0.125*(1.0-xi)*(1.0+eta)*(1.0-zeta); Ni[3] = 0.125*(1.0+xi)*(1.0+eta)*(1.0-zeta); Ni[4] = 0.125*(1.0-xi)*(1.0-eta)*(1.0+zeta); Ni[5] = 0.125*(1.0+xi)*(1.0-eta)*(1.0+zeta); Ni[6] = 0.125*(1.0-xi)*(1.0+eta)*(1.0+zeta); Ni[7] = 0.125*(1.0+xi)*(1.0+eta)*(1.0+zeta); xx = yy = zz = 0.0; for (p=0; p<8; p++ ) { xx += Ni[p]*xn[p]; yy += Ni[p]*yn[p]; zz += Ni[p]*zn[p]; } XX[k][j][i].x = xx; XX[k][j][i].y = yy; XX[k][j][i].z = zz; } } } ierr = DMDAVecRestoreArray(cda,Gcoords,&XX);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DMCreateSubDM_DA(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) { DM_DA *da = (DM_DA*) dm->data; PetscSection section; PetscErrorCode ierr; PetscFunctionBegin; if (subdm) { PetscSF sf; Vec coords; void *ctx; /* Cannot use DMClone since the dof stuff is mixed in. Ugh ierr = DMClone(dm, subdm);CHKERRQ(ierr); */ ierr = DMCreate(PetscObjectComm((PetscObject)dm), subdm);CHKERRQ(ierr); ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); ierr = DMSetPointSF(*subdm, sf);CHKERRQ(ierr); ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr); ierr = DMSetApplicationContext(*subdm, ctx);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr); if (coords) { ierr = DMSetCoordinatesLocal(*subdm, coords);CHKERRQ(ierr); } else { ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); if (coords) {ierr = DMSetCoordinates(*subdm, coords);CHKERRQ(ierr);} } ierr = DMSetType(*subdm, DMDA);CHKERRQ(ierr); ierr = DMSetDimension(*subdm, dm->dim);CHKERRQ(ierr); ierr = DMDASetSizes(*subdm, da->M, da->N, da->P);CHKERRQ(ierr); ierr = DMDASetNumProcs(*subdm, da->m, da->n, da->p);CHKERRQ(ierr); ierr = DMDASetBoundaryType(*subdm, da->bx, da->by, da->bz);CHKERRQ(ierr); ierr = DMDASetDof(*subdm, numFields);CHKERRQ(ierr); ierr = DMDASetStencilType(*subdm, da->stencil_type);CHKERRQ(ierr); ierr = DMDASetStencilWidth(*subdm, da->s);CHKERRQ(ierr); ierr = DMDASetOwnershipRanges(*subdm, da->lx, da->ly, da->lz);CHKERRQ(ierr); } ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); if (section) { ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr); } else { if (is) { PetscInt *indices, cnt = 0, dof = da->w, i, j; ierr = PetscMalloc1(da->Nlocal*numFields/dof, &indices);CHKERRQ(ierr); for (i = da->base/dof; i < (da->base+da->Nlocal)/dof; ++i) { for (j = 0; j < numFields; ++j) { indices[cnt++] = dof*i + fields[j]; } } if (cnt != da->Nlocal*numFields/dof) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Count %d does not equal expected value %d", cnt, da->Nlocal*numFields/dof); ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), cnt, indices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
/*@C DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA Not Collective Input Parameter: + dm - the DM - xc - the coordinates Level: intermediate .keywords: distributed array, get, component name .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDAGetCoordinateArray() @*/ PetscErrorCode DMDARestoreCoordinateArray(DM dm,void *xc) { PetscErrorCode ierr; DM cdm; Vec x; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr); ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(cdm,x,xc);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* FormFunctionLocalMMS2 - Evaluates nonlinear function, F(x) on local process patch */ PetscErrorCode FormFunctionLocalMMS2(DMDALocalInfo *info,PetscScalar **vx,PetscScalar **f,AppCtx *user) { PetscErrorCode ierr; PetscInt i,j; PetscReal lambda,hx,hy,hxdhy,hydhx; PetscScalar u,ue,uw,un,us,uxx,uyy; PetscReal x,y; DM coordDA; Vec coordinates; DMDACoor2d **coords; PetscFunctionBeginUser; lambda = user->param; hx = 1.0/(PetscReal)(info->mx-1); hy = 1.0/(PetscReal)(info->my-1); hxdhy = hx/hy; hydhx = hy/hx; /* Extract coordinates */ ierr = DMGetCoordinateDM(info->da, &coordDA);CHKERRQ(ierr); ierr = DMGetCoordinates(info->da, &coordinates);CHKERRQ(ierr); ierr = DMDAVecGetArray(coordDA, coordinates, &coords);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (j=info->ys; j<info->ys+info->ym; j++) { for (i=info->xs; i<info->xs+info->xm; i++) { if (i == 0 || j == 0 || i == info->mx-1 || j == info->my-1) { f[j][i] = 2.0*(hydhx+hxdhy)*vx[j][i]; } else { x = PetscRealPart(coords[j][i].x); y = PetscRealPart(coords[j][i].y); u = vx[j][i]; uw = vx[j][i-1]; ue = vx[j][i+1]; un = vx[j-1][i]; us = vx[j+1][i]; if (i-1 == 0) uw = 0.; if (i+1 == info->mx-1) ue = 0.; if (j-1 == 0) un = 0.; if (j+1 == info->my-1) us = 0.; uxx = (2.0*u - uw - ue)*hydhx; uyy = (2.0*u - un - us)*hxdhy; f[j][i] = uxx + uyy - hx*hy*(lambda*PetscExpScalar(u) + 2*PetscSqr(PETSC_PI)*PetscSinReal(PETSC_PI*x)*PetscSinReal(PETSC_PI*y) - lambda*exp(PetscSinReal(PETSC_PI*x)*PetscSinReal(PETSC_PI*y))); } } } ierr = DMDAVecRestoreArray(coordDA, coordinates, &coords);CHKERRQ(ierr); ierr = PetscLogFlops(11.0*info->ym*info->xm);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C DMDAGetLogicalCoordinate - Returns a the i,j,k logical coordinate for the closest mesh point to a x,y,z point in the coordinates of the DMDA Collective on DMDA Input Parameters: + da - the distributed array - x,y,z - the physical coordinates Output Parameters: + II, JJ, KK - the logical coordinate (-1 on processes that do not contain that point) - X, Y, Z, - (optional) the coordinates of the located grid point Level: advanced Notes: All processors that share the DMDA must call this with the same coordinate value .keywords: distributed array, get, processor subset @*/ PetscErrorCode DMDAGetLogicalCoordinate(DM da,PetscScalar x,PetscScalar y,PetscScalar z,PetscInt *II,PetscInt *JJ,PetscInt *KK,PetscScalar *X,PetscScalar *Y,PetscScalar *Z) { DM_DA *dd = (DM_DA*)da->data; PetscErrorCode ierr; Vec coors; DM dacoors; DMDACoor2d **c; PetscInt i,j,xs,xm,ys,ym; PetscReal d,D = PETSC_MAX_REAL,Dv; PetscMPIInt rank,root; PetscFunctionBegin; if (dd->dim == 1) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Cannot get point from 1d DMDA"); if (dd->dim == 3) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Cannot get point from 3d DMDA"); *II = -1; *JJ = -1; ierr = DMGetCoordinateDM(da,&dacoors);CHKERRQ(ierr); ierr = DMDAGetCorners(dacoors,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&coors);CHKERRQ(ierr); ierr = DMDAVecGetArray(dacoors,coors,&c);CHKERRQ(ierr); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { d = PetscSqrtReal(PetscRealPart( (c[j][i].x - x)*(c[j][i].x - x) + (c[j][i].y - y)*(c[j][i].y - y) )); if (d < D) { D = d; *II = i; *JJ = j; } } } ierr = MPI_Allreduce(&D,&Dv,1,MPIU_REAL,MPI_MIN,PetscObjectComm((PetscObject)da));CHKERRQ(ierr); if (D != Dv) { *II = -1; *JJ = -1; rank = 0; } else { *X = c[*JJ][*II].x; *Y = c[*JJ][*II].y; ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)da),&rank);CHKERRQ(ierr); rank++; } ierr = MPI_Allreduce(&rank,&root,1,MPI_INT,MPI_SUM,PetscObjectComm((PetscObject)da));CHKERRQ(ierr); root--; ierr = MPI_Bcast(X,1,MPIU_SCALAR,root,PetscObjectComm((PetscObject)da));CHKERRQ(ierr); ierr = MPI_Bcast(Y,1,MPIU_SCALAR,root,PetscObjectComm((PetscObject)da));CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dacoors,coors,&c);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { PetscInt dim = user->dim; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = DMPlexCreateBoxMesh(comm, dim, user->simplex, user->cells, NULL, NULL, NULL, PETSC_TRUE, dm);CHKERRQ(ierr); { Parameter *param; Vec coordinates; PetscScalar *coords; PetscReal alpha; PetscInt cdim, N, bs, i; ierr = DMGetCoordinateDim(*dm, &cdim);CHKERRQ(ierr); ierr = DMGetCoordinates(*dm, &coordinates);CHKERRQ(ierr); ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); if (bs != cdim) SETERRQ2(comm, PETSC_ERR_ARG_WRONG, "Invalid coordinate blocksize %D != embedding dimension %D", bs, cdim); ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); ierr = PetscBagGetData(user->bag, (void **) ¶m);CHKERRQ(ierr); alpha = param->alpha; for (i = 0; i < N; i += cdim) { PetscScalar x = coords[i+0]; PetscScalar y = coords[i+1]; coords[i+0] = PetscCosReal(alpha)*x - PetscSinReal(alpha)*y; coords[i+1] = PetscSinReal(alpha)*x + PetscCosReal(alpha)*y; } ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); ierr = DMSetCoordinates(*dm, coordinates);CHKERRQ(ierr); } { DM pdm = NULL; PetscPartitioner part; ierr = DMPlexGetPartitioner(*dm, &part);CHKERRQ(ierr); ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); ierr = DMPlexDistribute(*dm, 0, NULL, &pdm);CHKERRQ(ierr); if (pdm) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = pdm; } } ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ini_bou(Vec X,AppCtx* user) { PetscErrorCode ierr; DM cda; DMDACoor2d **coors; PetscScalar **p; Vec gc; PetscInt i,j; PetscInt xs,ys,xm,ym,M,N; PetscScalar xi,yi; PetscScalar sigmax=user->sigmax,sigmay=user->sigmay; PetscScalar rho =user->rho; PetscScalar mux =user->mux,muy=user->muy; PetscMPIInt rank; PetscFunctionBeginUser; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr); ierr = DMDAGetInfo(user->da,NULL,&M,&N,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); user->dx = (user->xmax - user->xmin)/(M-1); user->dy = (user->ymax - user->ymin)/(N-1); ierr = DMGetCoordinateDM(user->da,&cda); CHKERRQ(ierr); ierr = DMGetCoordinates(user->da,&gc); CHKERRQ(ierr); ierr = DMDAVecGetArray(cda,gc,&coors); CHKERRQ(ierr); ierr = DMDAVecGetArray(user->da,X,&p); CHKERRQ(ierr); ierr = DMDAGetCorners(cda,&xs,&ys,0,&xm,&ym,0); CHKERRQ(ierr); for (i=xs; i < xs+xm; i++) { for (j=ys; j < ys+ym; j++) { xi = coors[j][i].x; yi = coors[j][i].y; if (i == 0 || j == 0 || i == M-1 || j == N-1) p[j][i] = 0.0; else p[j][i] = (0.5/(PETSC_PI*sigmax*sigmay*PetscSqrtScalar(1.0-rho*rho)))*PetscExpScalar(-0.5/(1-rho*rho)*(PetscPowScalar((xi-mux)/sigmax,2) + PetscPowScalar((yi-muy)/sigmay,2) - 2*rho*(xi-mux)*(yi-muy)/(sigmax*sigmay))); } } /* p[N/2+N%2][M/2+M%2] = 1/(user->dx*user->dy); */ ierr = DMDAVecRestoreArray(cda,gc,&coors); CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->da,X,&p); CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { Vec u,xy; DM da; PetscErrorCode ierr; PetscInt m = 10, n = 10, dof = 2; PF pf; ierr = PetscInitialize(&argc,&argv,(char*)0,help); CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_BOX,m,n,PETSC_DECIDE,PETSC_DECIDE,dof,1,0,0,&da); CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,1.0); CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&u); CHKERRQ(ierr); ierr = DMGetCoordinates(da,&xy); CHKERRQ(ierr); ierr = DMDACreatePF(da,&pf); CHKERRQ(ierr); ierr = PFSet(pf,myfunction,0,0,0,0); CHKERRQ(ierr); ierr = PFSetFromOptions(pf); CHKERRQ(ierr); ierr = PFApplyVec(pf,xy,u); CHKERRQ(ierr); ierr = VecView(u,PETSC_VIEWER_DRAW_WORLD); CHKERRQ(ierr); /* Free work space. All PETSc objects should be destroyed when they are no longer needed. */ ierr = PFDestroy(&pf); CHKERRQ(ierr); ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
/* FormFunctionLocal - Evaluates nonlinear function, F(x). */ PetscErrorCode FormFunctionLocal(DMDALocalInfo *info,PetscScalar **x,PetscScalar **f,AppCtx *user) { DM coordDA; Vec coordinates; DMDACoor2d **coords; PetscScalar u, ux, uy, uxx, uyy; PetscReal D, K, hx, hy, hxdhy, hydhx; PetscInt i,j; PetscErrorCode ierr; PetscFunctionBeginUser; D = user->D; K = user->K; hx = 1.0/(PetscReal)(info->mx-1); hy = 1.0/(PetscReal)(info->my-1); hxdhy = hx/hy; hydhx = hy/hx; /* Compute function over the locally owned part of the grid */ ierr = DMGetCoordinateDM(info->da, &coordDA);CHKERRQ(ierr); ierr = DMGetCoordinates(info->da, &coordinates);CHKERRQ(ierr); ierr = DMDAVecGetArray(coordDA, coordinates, &coords);CHKERRQ(ierr); for (j=info->ys; j<info->ys+info->ym; j++) { for (i=info->xs; i<info->xs+info->xm; i++) { if (i == 0 || j == 0 || i == info->mx-1 || j == info->my-1) f[j][i] = x[j][i]; else { u = x[j][i]; ux = (x[j][i+1] - x[j][i])/hx; uy = (x[j+1][i] - x[j][i])/hy; uxx = (2.0*u - x[j][i-1] - x[j][i+1])*hydhx; uyy = (2.0*u - x[j-1][i] - x[j+1][i])*hxdhy; f[j][i] = D*(uxx + uyy) - (K*funcA(x[j][i], user)*PetscSqrtScalar(ux*ux + uy*uy) + funcU(&coords[j][i]))*hx*hy; if (PetscIsInfOrNanScalar(f[j][i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FP, "Invalid residual: %g", PetscRealPart(f[j][i])); } } } ierr = DMDAVecRestoreArray(coordDA, coordinates, &coords);CHKERRQ(ierr); ierr = PetscLogFlops(11*info->ym*info->xm);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DADefineXLinearField3D(DM da,Vec field) { PetscErrorCode ierr; PetscInt i,j,k; PetscInt sx,nx,sy,ny,sz,nz; Vec Gcoords; DMDACoor3d ***XX; PetscScalar ***FF; DM cda; PetscFunctionBeginUser; ierr = DMGetCoordinateDM(da,&cda);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&Gcoords);CHKERRQ(ierr); ierr = DMDAVecGetArray(cda,Gcoords,&XX);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,field,&FF);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&sx,&sy,&sz,&nx,&ny,&nz);CHKERRQ(ierr); for (k=sz; k<sz+nz; k++) { for (j=sy; j<sy+ny; j++ ) { for (i=sx; i<sx+nx; i++) { FF[k][j][i] = 10.0 + 4.05 * XX[k][j][i].x + 5.50 * XX[k][j][i].y + 1.33 * XX[k][j][i].z + 2.03 * XX[k][j][i].x * XX[k][j][i].y + 0.03 * XX[k][j][i].x * XX[k][j][i].z + 0.83 * XX[k][j][i].y * XX[k][j][i].z + 3.79 * XX[k][j][i].x * XX[k][j][i].y * XX[k][j][i].z; } } } ierr = DMDAVecRestoreArray(da,field,&FF);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(cda,Gcoords,&XX);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ComputeSolution(DM da,PetscGLL *gll,Vec u) { PetscErrorCode ierr; PetscInt j,xs,xn; PetscScalar *uu,*xx; PetscReal xd; Vec x; PetscFunctionBegin; ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xn,NULL,NULL);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&x);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,x,&xx);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,u,&uu);CHKERRQ(ierr); /* loop over local nodes */ for (j=xs; j<xs+xn; j++) { xd = xx[j]; uu[j] = (xd*xd - 1.0)*PetscCosReal(5.*PETSC_PI*xd); } ierr = DMDAVecRestoreArray(da,x,&xx);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,u,&uu);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA. Not Collective Input Parameter: . dm - the DM Output Parameters: + lmin - local minimum coordinates (length dim, optional) - lmax - local maximim coordinates (length dim, optional) Level: beginner .keywords: distributed array, get, coordinates .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox() @*/ PetscErrorCode DMDAGetLocalBoundingBox(DM dm,PetscReal lmin[],PetscReal lmax[]) { PetscErrorCode ierr; Vec coords = NULL; PetscInt dim,i,j; const PetscScalar *local_coords; PetscReal min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL}; PetscInt N,Ni; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); dim = dm->dim; ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); if (coords) { ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr); ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr); Ni = N/dim; for (i=0; i<Ni; i++) { for (j=0; j<3; j++) { min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0; max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0; } } ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr); } else { /* Just use grid indices */ DMDALocalInfo info; ierr = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr); min[0] = info.xs; min[1] = info.ys; min[2] = info.zs; max[0] = info.xs + info.xm-1; max[1] = info.ys + info.ym-1; max[2] = info.zs + info.zm-1; } if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);} if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);} PetscFunctionReturn(0); }
PetscErrorCode PostStep(TS ts) { PetscErrorCode ierr; Vec X,gc; AppCtx *user; PetscScalar sum = 0,asum; PetscReal t,**p; DMDACoor2d **coors; DM cda; PetscInt i,j,xs,ys,xm,ym; PetscFunctionBegin; ierr = TSGetApplicationContext(ts,&user);CHKERRQ(ierr); ierr = TSGetTime(ts,&t);CHKERRQ(ierr); ierr = TSGetSolution(ts,&X);CHKERRQ(ierr); ierr = DMGetCoordinateDM(user->da,&cda);CHKERRQ(ierr); ierr = DMDAGetCorners(cda,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr); ierr = DMGetCoordinates(user->da,&gc);CHKERRQ(ierr); ierr = DMDAVecGetArray(cda,gc,&coors);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->da,X,&p);CHKERRQ(ierr); for (i=xs; i < xs+xm; i++) { for (j=ys; j < ys+ym; j++) { // printf("i %d j %d y %g %g\n",i,j,coors[j][i].y,p[j][i]); if (coors[j][i].y < 5) sum += p[j][i]; } } ierr = DMDAVecRestoreArray(cda,gc,&coors);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->da,X,&p);CHKERRQ(ierr); ierr = MPI_Allreduce(&sum,&asum,1,MPIU_SCALAR,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"sum(p)*dw*dtheta at t = %f = %f\n",(double)t,(double)(asum));CHKERRQ(ierr); if (sum < 1.0e-2) { ierr = TSSetConvergedReason(ts,TS_CONVERGED_USER);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Exiting TS as the integral of PDF is almost zero\n");CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode DisplayLine(SNES snes,Vec X) { PetscInt r,i,j=0,k=0,xs,xm,ys,ym,zs,zm,mx,my,mz; PetscErrorCode ierr; Field ***x; CoordField ***c; DM da,cda; Vec C; PetscMPIInt size,rank; PetscFunctionBegin; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = SNESGetDM(snes,&da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&mx,&my,&mz,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da,&cda);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&C);CHKERRQ(ierr); j = my / 2; k = mz / 2; ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,X,&x);CHKERRQ(ierr); ierr = DMDAVecGetArray(cda,C,&c);CHKERRQ(ierr); for (r=0;r<size;r++) { if (rank == r) { if (j >= ys && j < ys+ym && k >= zs && k < zs+zm) { for (i=xs; i<xs+xm; i++) { ierr = PetscPrintf(PETSC_COMM_SELF,"%D %d %d: %f %f %f\n",i,0,0,(double)PetscRealPart(c[k][j][i][0] + x[k][j][i][0]),(double)PetscRealPart(c[k][j][i][1] + x[k][j][i][1]),(double)PetscRealPart(c[k][j][i][2] + x[k][j][i][2]));CHKERRQ(ierr); } } } ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr); } ierr = DMDAVecRestoreArray(da,X,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(cda,C,&c);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode DMDAVTKWriteAll_VTS(DM da,PetscViewer viewer) { #if defined(PETSC_USE_REAL_SINGLE) const char precision[] = "Float32"; #elif defined(PETSC_USE_REAL_DOUBLE) const char precision[] = "Float64"; #else const char precision[] = "UnknownPrecision"; #endif MPI_Comm comm = ((PetscObject)da)->comm; PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; PetscViewerVTKObjectLink link; FILE *fp; PetscMPIInt rank,size,tag; DMDALocalInfo info; PetscInt dim,mx,my,mz,bs,boffset,maxnnodes,i,j,k,f,r; PetscInt rloc[6],(*grloc)[6] = PETSC_NULL; PetscScalar *array,*array2; PetscReal gmin[3],gmax[3]; PetscErrorCode ierr; PetscFunctionBegin; #if defined(PETSC_USE_COMPLEX) SETERRQ(comm,PETSC_ERR_SUP,"Complex values not supported"); #endif ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); ierr = DMDAGetInfo(da,&dim, &mx,&my,&mz, 0,0,0, &bs,0,0,0,0,0);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); ierr = DMDAGetBoundingBox(da,gmin,gmax);CHKERRQ(ierr); ierr = PetscFOpen(comm,vtk->filename,"wb",&fp);CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp,"<?xml version=\"1.0\"?>\n");CHKERRQ(ierr); #ifdef PETSC_WORDS_BIGENDIAN ierr = PetscFPrintf(comm,fp,"<VTKFile type=\"StructuredGrid\" version=\"0.1\" byte_order=\"BigEndian\">\n");CHKERRQ(ierr); #else ierr = PetscFPrintf(comm,fp,"<VTKFile type=\"StructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n");CHKERRQ(ierr); #endif ierr = PetscFPrintf(comm,fp," <StructuredGrid WholeExtent=\"%D %D %D %D %D %D\">\n",0,mx-1,0,my-1,0,mz-1);CHKERRQ(ierr); if (!rank) {ierr = PetscMalloc(size*6*sizeof(PetscInt),&grloc);CHKERRQ(ierr);} rloc[0] = info.xs; rloc[1] = info.xm; rloc[2] = info.ys; rloc[3] = info.ym; rloc[4] = info.zs; rloc[5] = info.zm; ierr = MPI_Gather(rloc,6,MPIU_INT,&grloc[0][0],6,MPIU_INT,0,comm);CHKERRQ(ierr); /* Write XML header */ maxnnodes = 0; /* Used for the temporary array size on rank 0 */ boffset = 0; /* Offset into binary file */ for (r=0; r<size; r++) { PetscInt xs=-1,xm=-1,ys=-1,ym=-1,zs=-1,zm=-1,nnodes = 0; if (!rank) { xs = grloc[r][0]; xm = grloc[r][1]; ys = grloc[r][2]; ym = grloc[r][3]; zs = grloc[r][4]; zm = grloc[r][5]; nnodes = xm*ym*zm; } maxnnodes = PetscMax(maxnnodes,nnodes); #if 0 switch (dim) { case 1: ierr = PetscFPrintf(comm,fp," <Piece Extent=\"%D %D %D %D %D %D\">\n",xs,xs+xm-1,0,0,0,0);CHKERRQ(ierr); break; case 2: ierr = PetscFPrintf(comm,fp," <Piece Extent=\"%D %D %D %D %D %D\">\n",xs,xs+xm,ys+ym-1,xs,xs+xm-1,0,0);CHKERRQ(ierr); break; case 3: ierr = PetscFPrintf(comm,fp," <Piece Extent=\"%D %D %D %D %D %D\">\n",xs,xs+xm-1,ys,ys+ym-1,zs,zs+zm-1);CHKERRQ(ierr); break; default: SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"No support for dimension %D",dim); } #endif ierr = PetscFPrintf(comm,fp," <Piece Extent=\"%D %D %D %D %D %D\">\n",xs,xs+xm-1,ys,ys+ym-1,zs,zs+zm-1);CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp," <Points>\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp," <DataArray type=\"%s\" Name=\"Position\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%D\" />\n",precision,boffset);CHKERRQ(ierr); boffset += 3*nnodes*sizeof(PetscScalar) + sizeof(int); ierr = PetscFPrintf(comm,fp," </Points>\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp," <PointData Scalars=\"ScalarPointData\">\n");CHKERRQ(ierr); for (link=vtk->link; link; link=link->next) { Vec X = (Vec)link->vec; const char *vecname = ""; if (((PetscObject)X)->name || link != vtk->link) { /* If the object is already named, use it. If it is past the first link, name it to disambiguate. */ ierr = PetscObjectGetName((PetscObject)X,&vecname);CHKERRQ(ierr); } for (i=0; i<bs; i++) { char buf[256]; const char *fieldname; ierr = DMDAGetFieldName(da,i,&fieldname);CHKERRQ(ierr); if (!fieldname) { ierr = PetscSNPrintf(buf,sizeof(buf),"Unnamed%D",i);CHKERRQ(ierr); fieldname = buf; } ierr = PetscFPrintf(comm,fp," <DataArray type=\"%s\" Name=\"%s%s\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",precision,vecname,fieldname,boffset);CHKERRQ(ierr); boffset += nnodes*sizeof(PetscScalar) + sizeof(int); } } ierr = PetscFPrintf(comm,fp," </PointData>\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp," </Piece>\n");CHKERRQ(ierr); } ierr = PetscFPrintf(comm,fp," </StructuredGrid>\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp," <AppendedData encoding=\"raw\">\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp,"_");CHKERRQ(ierr); /* Now write the arrays. */ tag = ((PetscObject)viewer)->tag; ierr = PetscMalloc2(maxnnodes*PetscMax(3,bs),PetscScalar,&array,maxnnodes*3,PetscScalar,&array2);CHKERRQ(ierr); for (r=0; r<size; r++) { MPI_Status status; PetscInt xs=-1,xm=-1,ys=-1,ym=-1,zs=-1,zm=-1,nnodes = 0; if (!rank) { xs = grloc[r][0]; xm = grloc[r][1]; ys = grloc[r][2]; ym = grloc[r][3]; zs = grloc[r][4]; zm = grloc[r][5]; nnodes = xm*ym*zm; } else if (r == rank) { nnodes = info.xm*info.ym*info.zm; } { /* Write the coordinates */ Vec Coords; ierr = DMGetCoordinates(da,&Coords);CHKERRQ(ierr); if (Coords) { const PetscScalar *coords; ierr = VecGetArrayRead(Coords,&coords);CHKERRQ(ierr); if (!rank) { if (r) { PetscMPIInt nn; ierr = MPI_Recv(array,nnodes*dim,MPIU_SCALAR,r,tag,comm,&status);CHKERRQ(ierr); ierr = MPI_Get_count(&status,MPIU_SCALAR,&nn);CHKERRQ(ierr); if (nn != nnodes*dim) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Array size mismatch"); } else { ierr = PetscMemcpy(array,coords,nnodes*dim*sizeof(PetscScalar));CHKERRQ(ierr); } /* Transpose coordinates to VTK (C-style) ordering */ for (k=0; k<zm; k++) { for (j=0; j<ym; j++) { for (i=0; i<xm; i++) { PetscInt Iloc = i+xm*(j+ym*k); array2[Iloc*3+0] = array[Iloc*dim + 0]; array2[Iloc*3+1] = dim > 1 ? array[Iloc*dim + 1] : 0; array2[Iloc*3+2] = dim > 2 ? array[Iloc*dim + 2] : 0; } } } } else if (r == rank) { ierr = MPI_Send((void*)coords,nnodes*dim,MPIU_SCALAR,0,tag,comm);CHKERRQ(ierr); } ierr = VecRestoreArrayRead(Coords,&coords);CHKERRQ(ierr); } else { /* Fabricate some coordinates using grid index */ for (k=0; k<zm; k++) { for (j=0; j<ym; j++) { for (i=0; i<xm; i++) { PetscInt Iloc = i+xm*(j+ym*k); array2[Iloc*3+0] = xs+i; array2[Iloc*3+1] = ys+j; array2[Iloc*3+2] = zs+k; } } } } ierr = PetscViewerVTKFWrite(viewer,fp,array2,nnodes*3,PETSC_SCALAR);CHKERRQ(ierr); } /* Write each of the objects queued up for this file */ for (link=vtk->link; link; link=link->next) { Vec X = (Vec)link->vec; const PetscScalar *x; ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); if (!rank) { if (r) { PetscMPIInt nn; ierr = MPI_Recv(array,nnodes*bs,MPIU_SCALAR,r,tag,comm,&status);CHKERRQ(ierr); ierr = MPI_Get_count(&status,MPIU_SCALAR,&nn);CHKERRQ(ierr); if (nn != nnodes*bs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Array size mismatch receiving from rank %D",r); } else { ierr = PetscMemcpy(array,x,nnodes*bs*sizeof(PetscScalar));CHKERRQ(ierr); } for (f=0; f<bs; f++) { /* Extract and transpose the f'th field */ for (k=0; k<zm; k++) { for (j=0; j<ym; j++) { for (i=0; i<xm; i++) { PetscInt Iloc = i+xm*(j+ym*k); array2[Iloc] = array[Iloc*bs + f]; } } } ierr = PetscViewerVTKFWrite(viewer,fp,array2,nnodes,PETSC_SCALAR);CHKERRQ(ierr); } } else if (r == rank) { ierr = MPI_Send((void*)x,nnodes*bs,MPIU_SCALAR,0,tag,comm);CHKERRQ(ierr); } ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); } } ierr = PetscFree2(array,array2);CHKERRQ(ierr); ierr = PetscFree(grloc);CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp,"\n </AppendedData>\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp,"</VTKFile>\n");CHKERRQ(ierr); ierr = PetscFClose(comm,fp);CHKERRQ(ierr); PetscFunctionReturn(0); }