Fixed a bug with SetNeighborPart and SetSharedPart

The previous code did not remove overlap in either the original boxes passed in
by the user or the constructed boxes for each variable type.  This caused calls
to AddValues to double count contributions in some places for vectors.
This commit is contained in:
Rob Falgout 2016-03-11 09:46:34 -08:00
parent e51d1ad902
commit 3ed2260394
4 changed files with 145 additions and 52 deletions

View File

@ -572,14 +572,19 @@ HYPRE_SStructGridAssemble( HYPRE_SStructGrid grid )
hypre_SStructNeighbor *neighbor; hypre_SStructNeighbor *neighbor;
hypre_IndexRef nbor_offset; hypre_IndexRef nbor_offset;
hypre_SStructNeighbor *vneighbor; hypre_SStructNeighbor *vneighbor;
hypre_Box *box; HYPRE_Int *coord, *dir;
HYPRE_Int *ilower, *coord, *dir; hypre_Index *fr_roots, *to_roots;
hypre_BoxArrayArray *nbor_boxes;
hypre_BoxArray *nbor_boxa;
hypre_BoxArray *sub_boxa;
hypre_BoxArray *tmp_boxa;
hypre_Box *nbor_box, *box;
hypre_SStructPGrid *pgrid; hypre_SStructPGrid *pgrid;
HYPRE_SStructVariable *vartypes; HYPRE_SStructVariable *vartypes;
hypre_Index varoffset; hypre_Index varoffset;
HYPRE_Int nvars; HYPRE_Int nvars;
HYPRE_Int part, var, b, vb, d, i, valid; HYPRE_Int part, var, b, vb, d, i, valid;
HYPRE_Int nbor_part, sub_part;
/*------------------------------------------------------------- /*-------------------------------------------------------------
* if I own no data on some part, prune that part's neighbor info * if I own no data on some part, prune that part's neighbor info
@ -677,6 +682,9 @@ HYPRE_SStructGridAssemble( HYPRE_SStructGrid grid )
* Set up vneighbor info * Set up vneighbor info
*-------------------------------------------------*/ *-------------------------------------------------*/
box = hypre_BoxCreate(ndim);
tmp_boxa = hypre_BoxArrayCreate(0, ndim);
nvneighbors = hypre_TAlloc(HYPRE_Int *, nparts); nvneighbors = hypre_TAlloc(HYPRE_Int *, nparts);
vneighbors = hypre_TAlloc(hypre_SStructNeighbor **, nparts); vneighbors = hypre_TAlloc(hypre_SStructNeighbor **, nparts);
@ -690,33 +698,35 @@ HYPRE_SStructGridAssemble( HYPRE_SStructGrid grid )
for (var = 0; var < nvars; var++) for (var = 0; var < nvars; var++)
{ {
vneighbors[part][var] = hypre_TAlloc(hypre_SStructNeighbor, /* Put each new vneighbor box into a BoxArrayArray so we can remove overlap */
nneighbors[part]); nbor_boxes = hypre_BoxArrayArrayCreate(nneighbors[part], ndim);
fr_roots = hypre_TAlloc(hypre_Index, nneighbors[part]);
hypre_SStructVariableGetOffset((hypre_SStructVariable) vartypes[var], to_roots = hypre_TAlloc(hypre_Index, nneighbors[part]);
ndim, varoffset); hypre_SStructVariableGetOffset((hypre_SStructVariable) vartypes[var], ndim, varoffset);
nvneighbors[part][var] = 0;
vb = 0;
for (b = 0; b < nneighbors[part]; b++) for (b = 0; b < nneighbors[part]; b++)
{ {
neighbor = &neighbors[part][b]; neighbor = &neighbors[part][b];
nbor_offset = nbor_offsets[part][b]; nbor_offset = nbor_offsets[part][b];
vneighbor = &vneighbors[part][var][vb];
/* set pointers to vneighbor data */ /* Create var-centered vneighbor box from cell-centered neighbor box */
box = hypre_SStructNeighborBox(vneighbor);
ilower = hypre_SStructNeighborILower(vneighbor);
coord = hypre_SStructNeighborCoord(vneighbor);
dir = hypre_SStructNeighborDir(vneighbor);
/* copy neighbor data into vneighbor */
hypre_CopyBox(hypre_SStructNeighborBox(neighbor), box); hypre_CopyBox(hypre_SStructNeighborBox(neighbor), box);
hypre_SStructNeighborPart(vneighbor) =
hypre_SStructNeighborPart(neighbor);
hypre_CopyIndex(hypre_SStructNeighborILower(neighbor), ilower);
hypre_CopyIndex(hypre_SStructNeighborCoord(neighbor), coord);
hypre_CopyIndex(hypre_SStructNeighborDir(neighbor), dir);
hypre_SStructCellBoxToVarBox(box, nbor_offset, varoffset, &valid); hypre_SStructCellBoxToVarBox(box, nbor_offset, varoffset, &valid);
/* it's important to change ilower */ /* It is possible to have empty vneighbor boxes. For example, if
* only faces are shared (see SetSharedPart), then the vneighbor
* boxes for cell variables will be empty. */
if ( !(valid && hypre_BoxVolume(box)) )
{
continue;
}
/* Save root mapping information for later */
hypre_CopyIndex(hypre_BoxIMin(box), fr_roots[b]);
hypre_CopyIndex(hypre_SStructNeighborILower(neighbor), to_roots[b]);
/* It's important to adjust to_root (ilower) */
coord = hypre_SStructNeighborCoord(neighbor);
dir = hypre_SStructNeighborDir(neighbor);
for (d = 0; d < ndim; d++) for (d = 0; d < ndim; d++)
{ {
/* Compare the imin of the neighbor cell box ('i') to its imin /* Compare the imin of the neighbor cell box ('i') to its imin
@ -731,18 +741,63 @@ HYPRE_SStructGridAssemble( HYPRE_SStructGrid grid )
if (((dir[d] > 0) && (hypre_BoxIMinD(box, d) != i)) || if (((dir[d] > 0) && (hypre_BoxIMinD(box, d) != i)) ||
((dir[d] < 0) && (hypre_BoxIMinD(box, d) == i))) ((dir[d] < 0) && (hypre_BoxIMinD(box, d) == i)))
{ {
hypre_IndexD(ilower, coord[d]) -= hypre_IndexD(varoffset, d); hypre_IndexD(to_roots[b], coord[d]) -= hypre_IndexD(varoffset, d);
} }
} }
/* some variable types may lead to empty variable boxes? */
if (valid && hypre_BoxVolume(box)) /* Add box to the nbor_boxes */
nbor_boxa = hypre_BoxArrayArrayBoxArray(nbor_boxes, b);
hypre_AppendBox(box, nbor_boxa);
/* Make sure that the nbor_boxes don't overlap */
nbor_part = hypre_SStructNeighborPart(neighbor);
for (i = 0; i < b; i++)
{ {
neighbor = &neighbors[part][i];
sub_part = hypre_SStructNeighborPart(neighbor);
/* Only subtract boxes on the same neighbor part */
if (nbor_part == sub_part)
{
sub_boxa = hypre_BoxArrayArrayBoxArray(nbor_boxes, i);
/* nbor_boxa -= sub_boxa */
hypre_SubtractBoxArrays(nbor_boxa, sub_boxa, tmp_boxa);
}
}
nvneighbors[part][var] += hypre_BoxArraySize(nbor_boxa);
}
/* Set up vneighbors for this (part, var) */
vneighbors[part][var] = hypre_TAlloc(hypre_SStructNeighbor, nvneighbors[part][var]);
vb = 0;
for (b = 0; b < nneighbors[part]; b++)
{
neighbor = &neighbors[part][b];
nbor_boxa = hypre_BoxArrayArrayBoxArray(nbor_boxes, b);
nbor_part = hypre_SStructNeighborPart(neighbor);
coord = hypre_SStructNeighborCoord(neighbor);
dir = hypre_SStructNeighborDir(neighbor);
hypre_ForBoxI(i, nbor_boxa)
{
vneighbor = &vneighbors[part][var][vb];
nbor_box = hypre_BoxArrayBox(nbor_boxa, i);
hypre_CopyBox(nbor_box, hypre_SStructNeighborBox(vneighbor));
hypre_SStructNeighborPart(vneighbor) = nbor_part;
hypre_SStructIndexToNborIndex(hypre_BoxIMin(nbor_box),
fr_roots[b], to_roots[b], coord, dir, ndim,
hypre_SStructNeighborILower(vneighbor));
hypre_CopyIndex(coord, hypre_SStructNeighborCoord(vneighbor));
hypre_CopyIndex(dir, hypre_SStructNeighborDir(vneighbor));
vb++; vb++;
} }
} /* end of neighbor loop */ } /* end of vneighbor box loop */
nvneighbors[part][var] = vb; hypre_BoxArrayArrayDestroy(nbor_boxes);
hypre_TFree(fr_roots);
hypre_TFree(to_roots);
} /* end of variables loop */ } /* end of variables loop */
} /* end of part loop */ } /* end of part loop */
@ -750,6 +805,9 @@ HYPRE_SStructGridAssemble( HYPRE_SStructGrid grid )
hypre_SStructGridNVNeighbors(grid) = nvneighbors; hypre_SStructGridNVNeighbors(grid) = nvneighbors;
hypre_SStructGridVNeighbors(grid) = vneighbors; hypre_SStructGridVNeighbors(grid) = vneighbors;
hypre_BoxArrayDestroy(tmp_boxa);
hypre_BoxDestroy(box);
/*------------------------------------------------- /*-------------------------------------------------
* Assemble the box manager info * Assemble the box manager info
*-------------------------------------------------*/ *-------------------------------------------------*/

View File

@ -912,8 +912,10 @@ HYPRE_Int hypre_SStructBoxManEntryGetGlobalGhrank ( hypre_BoxManEntry *entry , h
HYPRE_Int hypre_SStructBoxManEntryGetProcess ( hypre_BoxManEntry *entry , HYPRE_Int *proc_ptr ); HYPRE_Int hypre_SStructBoxManEntryGetProcess ( hypre_BoxManEntry *entry , HYPRE_Int *proc_ptr );
HYPRE_Int hypre_SStructBoxManEntryGetBoxnum ( hypre_BoxManEntry *entry , HYPRE_Int *id_ptr ); HYPRE_Int hypre_SStructBoxManEntryGetBoxnum ( hypre_BoxManEntry *entry , HYPRE_Int *id_ptr );
HYPRE_Int hypre_SStructBoxManEntryGetPart ( hypre_BoxManEntry *entry , HYPRE_Int part , HYPRE_Int *part_ptr ); HYPRE_Int hypre_SStructBoxManEntryGetPart ( hypre_BoxManEntry *entry , HYPRE_Int part , HYPRE_Int *part_ptr );
HYPRE_Int hypre_SStructBoxToNborBox ( hypre_Box *box , hypre_Index index , hypre_Index nbor_index , hypre_Index coord , hypre_Index dir ); HYPRE_Int hypre_SStructIndexToNborIndex( hypre_Index index , hypre_Index root , hypre_Index nbor_root , hypre_Index coord , hypre_Index dir , HYPRE_Int ndim , hypre_Index nbor_index );
HYPRE_Int hypre_SStructNborBoxToBox ( hypre_Box *nbor_box , hypre_Index index , hypre_Index nbor_index , hypre_Index coord , hypre_Index dir ); HYPRE_Int hypre_SStructBoxToNborBox ( hypre_Box *box , hypre_Index root , hypre_Index nbor_root , hypre_Index coord , hypre_Index dir );
HYPRE_Int hypre_SStructNborIndexToIndex( hypre_Index nbor_index , hypre_Index root , hypre_Index nbor_root , hypre_Index coord , hypre_Index dir , HYPRE_Int ndim , hypre_Index index );
HYPRE_Int hypre_SStructNborBoxToBox ( hypre_Box *nbor_box , hypre_Index root , hypre_Index nbor_root , hypre_Index coord , hypre_Index dir );
HYPRE_Int hypre_SStructVarToNborVar ( hypre_SStructGrid *grid , HYPRE_Int part , HYPRE_Int var , HYPRE_Int *coord , HYPRE_Int *nbor_var_ptr ); HYPRE_Int hypre_SStructVarToNborVar ( hypre_SStructGrid *grid , HYPRE_Int part , HYPRE_Int var , HYPRE_Int *coord , HYPRE_Int *nbor_var_ptr );
HYPRE_Int hypre_SStructGridSetNumGhost ( hypre_SStructGrid *grid , HYPRE_Int *num_ghost ); HYPRE_Int hypre_SStructGridSetNumGhost ( hypre_SStructGrid *grid , HYPRE_Int *num_ghost );
HYPRE_Int hypre_SStructBoxManEntryGetGlobalRank ( hypre_BoxManEntry *entry , hypre_Index index , HYPRE_Int *rank_ptr , HYPRE_Int type ); HYPRE_Int hypre_SStructBoxManEntryGetGlobalRank ( hypre_BoxManEntry *entry , hypre_Index index , HYPRE_Int *rank_ptr , HYPRE_Int type );

View File

@ -121,8 +121,10 @@ HYPRE_Int hypre_SStructBoxManEntryGetGlobalGhrank ( hypre_BoxManEntry *entry , h
HYPRE_Int hypre_SStructBoxManEntryGetProcess ( hypre_BoxManEntry *entry , HYPRE_Int *proc_ptr ); HYPRE_Int hypre_SStructBoxManEntryGetProcess ( hypre_BoxManEntry *entry , HYPRE_Int *proc_ptr );
HYPRE_Int hypre_SStructBoxManEntryGetBoxnum ( hypre_BoxManEntry *entry , HYPRE_Int *id_ptr ); HYPRE_Int hypre_SStructBoxManEntryGetBoxnum ( hypre_BoxManEntry *entry , HYPRE_Int *id_ptr );
HYPRE_Int hypre_SStructBoxManEntryGetPart ( hypre_BoxManEntry *entry , HYPRE_Int part , HYPRE_Int *part_ptr ); HYPRE_Int hypre_SStructBoxManEntryGetPart ( hypre_BoxManEntry *entry , HYPRE_Int part , HYPRE_Int *part_ptr );
HYPRE_Int hypre_SStructBoxToNborBox ( hypre_Box *box , hypre_Index index , hypre_Index nbor_index , hypre_Index coord , hypre_Index dir ); HYPRE_Int hypre_SStructIndexToNborIndex( hypre_Index index , hypre_Index root , hypre_Index nbor_root , hypre_Index coord , hypre_Index dir , HYPRE_Int ndim , hypre_Index nbor_index );
HYPRE_Int hypre_SStructNborBoxToBox ( hypre_Box *nbor_box , hypre_Index index , hypre_Index nbor_index , hypre_Index coord , hypre_Index dir ); HYPRE_Int hypre_SStructBoxToNborBox ( hypre_Box *box , hypre_Index root , hypre_Index nbor_root , hypre_Index coord , hypre_Index dir );
HYPRE_Int hypre_SStructNborIndexToIndex( hypre_Index nbor_index , hypre_Index root , hypre_Index nbor_root , hypre_Index coord , hypre_Index dir , HYPRE_Int ndim , hypre_Index index );
HYPRE_Int hypre_SStructNborBoxToBox ( hypre_Box *nbor_box , hypre_Index root , hypre_Index nbor_root , hypre_Index coord , hypre_Index dir );
HYPRE_Int hypre_SStructVarToNborVar ( hypre_SStructGrid *grid , HYPRE_Int part , HYPRE_Int var , HYPRE_Int *coord , HYPRE_Int *nbor_var_ptr ); HYPRE_Int hypre_SStructVarToNborVar ( hypre_SStructGrid *grid , HYPRE_Int part , HYPRE_Int var , HYPRE_Int *coord , HYPRE_Int *nbor_var_ptr );
HYPRE_Int hypre_SStructGridSetNumGhost ( hypre_SStructGrid *grid , HYPRE_Int *num_ghost ); HYPRE_Int hypre_SStructGridSetNumGhost ( hypre_SStructGrid *grid , HYPRE_Int *num_ghost );
HYPRE_Int hypre_SStructBoxManEntryGetGlobalRank ( hypre_BoxManEntry *entry , hypre_Index index , HYPRE_Int *rank_ptr , HYPRE_Int type ); HYPRE_Int hypre_SStructBoxManEntryGetGlobalRank ( hypre_BoxManEntry *entry , hypre_Index index , HYPRE_Int *rank_ptr , HYPRE_Int type );

View File

@ -1797,10 +1797,30 @@ hypre_SStructBoxManEntryGetPart( hypre_BoxManEntry *entry,
* *
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
HYPRE_Int
hypre_SStructIndexToNborIndex( hypre_Index index,
hypre_Index root,
hypre_Index nbor_root,
hypre_Index coord,
hypre_Index dir,
HYPRE_Int ndim,
hypre_Index nbor_index )
{
HYPRE_Int d, nd;
for (d = 0; d < ndim; d++)
{
nd = coord[d];
nbor_index[nd] = nbor_root[nd] + (index[d] - root[d]) * dir[d];
}
return hypre_error_flag;
}
HYPRE_Int HYPRE_Int
hypre_SStructBoxToNborBox( hypre_Box *box, hypre_SStructBoxToNborBox( hypre_Box *box,
hypre_Index index, hypre_Index root,
hypre_Index nbor_index, hypre_Index nbor_root,
hypre_Index coord, hypre_Index coord,
hypre_Index dir ) hypre_Index dir )
{ {
@ -1808,15 +1828,10 @@ hypre_SStructBoxToNborBox( hypre_Box *box,
HYPRE_Int *imax = hypre_BoxIMax(box); HYPRE_Int *imax = hypre_BoxIMax(box);
HYPRE_Int ndim = hypre_BoxNDim(box); HYPRE_Int ndim = hypre_BoxNDim(box);
hypre_Index nbor_imin, nbor_imax; hypre_Index nbor_imin, nbor_imax;
HYPRE_Int d;
HYPRE_Int d, nd; hypre_SStructIndexToNborIndex(imin, root, nbor_root, coord, dir, ndim, nbor_imin);
hypre_SStructIndexToNborIndex(imax, root, nbor_root, coord, dir, ndim, nbor_imax);
for (d = 0; d < ndim; d++)
{
nd = coord[d];
nbor_imin[nd] = nbor_index[nd] + (imin[d] - index[d]) * dir[d];
nbor_imax[nd] = nbor_index[nd] + (imax[d] - index[d]) * dir[d];
}
for (d = 0; d < ndim; d++) for (d = 0; d < ndim; d++)
{ {
@ -1831,10 +1846,31 @@ hypre_SStructBoxToNborBox( hypre_Box *box,
* See "Mapping Notes" in comment for `hypre_SStructBoxToNborBox'. * See "Mapping Notes" in comment for `hypre_SStructBoxToNborBox'.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
HYPRE_Int
hypre_SStructNborIndexToIndex( hypre_Index nbor_index,
hypre_Index root,
hypre_Index nbor_root,
hypre_Index coord,
hypre_Index dir,
HYPRE_Int ndim,
hypre_Index index )
{
HYPRE_Int d, nd;
for (d = 0; d < ndim; d++)
{
nd = coord[d];
index[d] = root[d] + (nbor_index[nd] - nbor_root[nd]) * dir[d];
}
return hypre_error_flag;
}
HYPRE_Int HYPRE_Int
hypre_SStructNborBoxToBox( hypre_Box *nbor_box, hypre_SStructNborBoxToBox( hypre_Box *nbor_box,
hypre_Index index, hypre_Index root,
hypre_Index nbor_index, hypre_Index nbor_root,
hypre_Index coord, hypre_Index coord,
hypre_Index dir ) hypre_Index dir )
{ {
@ -1842,15 +1878,10 @@ hypre_SStructNborBoxToBox( hypre_Box *nbor_box,
HYPRE_Int *nbor_imax = hypre_BoxIMax(nbor_box); HYPRE_Int *nbor_imax = hypre_BoxIMax(nbor_box);
HYPRE_Int ndim = hypre_BoxNDim(nbor_box); HYPRE_Int ndim = hypre_BoxNDim(nbor_box);
hypre_Index imin, imax; hypre_Index imin, imax;
HYPRE_Int d;
HYPRE_Int d, nd; hypre_SStructNborIndexToIndex(nbor_imin, root, nbor_root, coord, dir, ndim, imin);
hypre_SStructNborIndexToIndex(nbor_imax, root, nbor_root, coord, dir, ndim, imax);
for (d = 0; d < ndim; d++)
{
nd = coord[d];
imin[d] = index[d] + (nbor_imin[nd] - nbor_index[nd]) * dir[d];
imax[d] = index[d] + (nbor_imax[nd] - nbor_index[nd]) * dir[d];
}
for (d = 0; d < ndim; d++) for (d = 0; d < ndim; d++)
{ {