Пример #1
0
PetscErrorCode ef_boundary_apply(ef_boundary *bnd, Mat A, DM da)
{
	PetscErrorCode ierr;
	int i;
	PetscInt level;

	ierr = DMGetCoarsenLevel(da, &level);CHKERRQ(ierr);

	for (i = 0; i < bnd->num_bc; i++) {
		if (bnd->bc[i]->patch->bc_type == EF_NEUMANN) {
			ierr = ef_bc_apply(bnd->bc[i], A, da);CHKERRQ(ierr);
		}
	}
	for (i = 0; i < bnd->num_bc; i++) {
		if (bnd->bc[i]->patch->bc_type == EF_DIRICHLET_G ||
		    bnd->bc[i]->patch->bc_type == EF_DIRICHLET_P) {
			ierr = ef_bc_apply(bnd->bc[i], A, da);CHKERRQ(ierr);
		}
	}

	if (level) { // prepare rhs transform. for coarse levels
		ierr = ef_boundary_apply_rhs(bnd, da);CHKERRQ(ierr);
	}

	// temporary symmetric Dirchlet hack
	ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
	ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
	ierr = MatMult(A, bnd->levels[level].g, bnd->levels[level].ag);CHKERRQ(ierr);

	for (i = 0; i < bnd->num_bc; i++) {
		ierr = ef_bc_symmetric(bnd->bc[i], A, da);CHKERRQ(ierr);
	}

	return 0;
}
Пример #2
0
static PetscErrorCode update_dirichlet_sym_3d(ef_bc *bc, Mat A, DM da)
{
	PetscErrorCode ierr;
	PetscInt i,j,k,cnt;
	PetscInt ngx, ngy, ngz;
	PetscScalar v[6];
	MatStencil row[6], col;
	PetscInt level;
	ef_patch *patch = bc->patch;

	ierr = DMGetCoarsenLevel(da, &level);CHKERRQ(ierr);

	ierr = DMDAGetInfo(da, 0, &ngx, &ngy, &ngz,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);

	for (i = 0; i < 6; i++) v[i] = 0;
	for (k = patch->corners[level].is[2]; k <= patch->corners[level].ie[2]; k++) {
		for (j = patch->corners[level].is[1]; j <= patch->corners[level].ie[1]; j++) {
			for (i = patch->corners[level].is[0]; i <= patch->corners[level].ie[0]; i++) {
				col.i = i; col.j = j; col.k = k;
				cnt = 0;

				if (i-1 < patch->corners[level].is[0] &&
				    i-1 >= 0) {
					row[cnt].i = i-1; row[cnt].j = j; row[cnt].k = k;
					cnt++;
				}
				if (i+1 > patch->corners[level].ie[0] &&
				    i+1 <= ngx-1) {
					row[cnt].i = i+1; row[cnt].j = j; row[cnt].k = k;
					cnt++;
				}
				if (j-1 < patch->corners[level].is[1] &&
				    j-1 >= 0) {
					row[cnt].i = i; row[cnt].j = j-1; row[cnt].k = k;
					cnt++;
				}
				if (j+1 > patch->corners[level].ie[1] &&
				    j+1 <= ngy-1) {
					row[cnt].i = i; row[cnt].j = j+1; row[cnt].k = k;
					cnt++;
				}
				if (k-1 < patch->corners[level].is[2] &&
				    k-1 >= 0) {
					row[cnt].i = i; row[cnt].j = j; row[cnt].k = k-1;
					cnt++;
				}
				if (k+1 > patch->corners[level].ie[2] &&
				    k+1 <= ngz-1) {
					row[cnt].i = i; row[cnt].j = j; row[cnt].k = k+1;
					cnt++;
				}

				ierr = MatSetValuesStencil(A, cnt, row, 1, &col, v, INSERT_VALUES);CHKERRQ(ierr);
			}
		}
	}

	return 0;
}
Пример #3
0
static PetscErrorCode apply_dirichlet_3d(ef_bc *bc, Mat A, DM da)
{
	PetscErrorCode ierr;
	PetscInt i,j,k,cnt;
	PetscInt ngx, ngy, ngz;
	PetscScalar v[7];
	MatStencil row, col[7];
	PetscInt level;
	ef_patch *patch = bc->patch;

	ierr = DMGetCoarsenLevel(da, &level);CHKERRQ(ierr);

	ierr = DMDAGetInfo(da, 0, &ngx, &ngy, &ngz,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);

	v[0] = 1.0;
	for (k = patch->corners[level].is[2]; k <= patch->corners[level].ie[2]; k++) {
		for (j = patch->corners[level].is[1]; j <= patch->corners[level].ie[1]; j++) {
			for (i = patch->corners[level].is[0]; i <= patch->corners[level].ie[0]; i++) {
				row.i = i; row.j = j; row.k = k;
				col[0].i = i; col[0].j = j; col[0].k = k;
				cnt = 1;

				if (i != 0) {
					col[cnt].i = i-1; col[cnt].j = j; col[cnt].k = k;
					v[cnt] = 0; cnt++;
				}
				if (j != 0) {
					col[cnt].i = i; col[cnt].j = j-1; col[cnt].k = k;
					v[cnt] = 0; cnt++;
				}
				if (k != 0) {
					col[cnt].i = i; col[cnt].j = j; col[cnt].k = k-1;
					v[cnt] = 0; cnt++;
				}
				if (i != ngx - 1) {
					col[cnt].i = i+1; col[cnt].j = j; col[cnt].k = k;
					v[cnt] = 0; cnt++;
				}
				if (j != ngy - 1) {
					col[cnt].i = i; col[cnt].j = j+1; col[cnt].k = k;
					v[cnt] = 0; cnt++;
				}
				if (k != ngz - 1) {
					col[cnt].i = i; col[cnt].j = j; col[cnt].k = k+1;
					v[cnt] = 0; cnt++;
				}

				ierr = MatSetValuesStencil(A, 1, &row, cnt, col, v, INSERT_VALUES);CHKERRQ(ierr);
			}
		}
	}

	return 0;
}
Пример #4
0
/*@
   DMDAGetReducedDMDA - Gets the DMDA with the same layout but with fewer or more fields

   Collective on DMDA

   Input Parameters:
+  da - the distributed array
-  nfields - number of fields in new DMDA

   Output Parameter:
.  nda - the new DMDA

  Level: intermediate

.keywords: distributed array, get, corners, nodes, local indices, coordinates

.seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates()
@*/
PetscErrorCode  DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda)
{
  PetscErrorCode   ierr;
  DM_DA            *dd = (DM_DA*)da->data;
  PetscInt         s,m,n,p,M,N,P,dim,Mo,No,Po;
  const PetscInt   *lx,*ly,*lz;
  DMBoundaryType   bx,by,bz;
  DMDAStencilType  stencil_type;
  PetscInt         ox,oy,oz;
  PetscInt         cl,rl;

  PetscFunctionBegin;
  dim = da->dim;
  M   = dd->M;
  N   = dd->N;
  P   = dd->P;
  m   = dd->m;
  n   = dd->n;
  p   = dd->p;
  s   = dd->s;
  bx  = dd->bx;
  by  = dd->by;
  bz  = dd->bz;

  stencil_type = dd->stencil_type;

  ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
  if (dim == 1) {
    ierr = DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
  } else if (dim == 2) {
    ierr = DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
  } else if (dim == 3) {
    ierr = DMDACreate3d(PetscObjectComm((PetscObject)da),bx,by,bz,stencil_type,M,N,P,m,n,p,nfields,s,lx,ly,lz,nda);CHKERRQ(ierr);
  }
  ierr = DMSetUp(*nda);CHKERRQ(ierr);
  if (da->coordinates) {
    ierr = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr);
    (*nda)->coordinates = da->coordinates;
  }

  /* allow for getting a reduced DA corresponding to a domain decomposition */
  ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr);
  ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr);

  /* allow for getting a reduced DA corresponding to a coarsened DA */
  ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr);
  ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr);

  (*nda)->levelup   = rl;
  (*nda)->leveldown = cl;
  PetscFunctionReturn(0);
}
Пример #5
0
static PetscErrorCode apply_rhs(ef_bc *bc, DM da)
{
	PetscErrorCode ierr;
	PetscInt dim;
	PetscInt level;

	ierr = DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr);

	ierr = DMGetCoarsenLevel(da, &level);CHKERRQ(ierr);
	if (!level) {
		if (dim == 2) {
			ierr = apply_dirichlet_rhs(bc, da);CHKERRQ(ierr);
		} else if (dim == 3) {
			ierr = apply_dirichlet_rhs_3d(bc, da);CHKERRQ(ierr);
		}
	}

	return 0;
}
Пример #6
0
static PetscErrorCode apply_dirichlet_rhs_3d(ef_bc *bc, DM da)
{
	PetscErrorCode ierr;
	PetscInt i,j,k,xs,ys,zs,xe,ye,ze,ym,xm,zm;
	PetscInt level;
	PetscScalar ***gvec, ***gcomp;
	double ***dirichlet;
	ef_dmap *dmap;
	int stride[3];
	ef_patch *patch = bc->patch;

	ierr = DMGetCoarsenLevel(da, &level);CHKERRQ(ierr);

	ys = patch->gis[1]-1; xs = patch->gis[0]-1; zs = patch->gis[2]-1;
	ye = patch->gie[1];   xe = patch->gie[0]; ze = patch->gie[2];
	ym = patch->gie[1] - patch->gis[1] + 1;
	xm = patch->gie[0] - patch->gis[0] + 1;
	zm = patch->gie[2] - patch->gis[2] + 1;
	stride[0] = xm; stride[1] = ym; stride[2] = zm;

	dmap = ef_dmap_create_3d(xs, ys, zs, xm, ym, zm, stride);
	ierr = ef_dmap_get(dmap, patch->dirichlet, &dirichlet);CHKERRQ(ierr);

	ierr = DMDAVecGetArray(da, bc->levels[level].g, &gvec);CHKERRQ(ierr);
	ierr = DMDAVecGetArray(da, bc->levels[level].gcomp, &gcomp);CHKERRQ(ierr);
	for (k = zs; k < ze; k++) {
		for (j = ys; j < ye; j++) {
			for (i = xs; i < xe; i++) {
				gvec[k][j][i] = dirichlet[k][j][i];
				gcomp[k][j][i] = 0.0;
			}
		}
	}
	ierr = ef_dmap_restore(dmap, &dirichlet);CHKERRQ(ierr);
	ierr = DMDAVecRestoreArray(da, bc->levels[level].g, &gvec);CHKERRQ(ierr);
	ierr = DMDAVecRestoreArray(da, bc->levels[level].gcomp, &gcomp);CHKERRQ(ierr);


	ef_dmap_destroy(dmap); free(dmap);

	return 0;
}