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:
parent
e51d1ad902
commit
3ed2260394
@ -572,14 +572,19 @@ HYPRE_SStructGridAssemble( HYPRE_SStructGrid grid )
|
||||
hypre_SStructNeighbor *neighbor;
|
||||
hypre_IndexRef nbor_offset;
|
||||
hypre_SStructNeighbor *vneighbor;
|
||||
hypre_Box *box;
|
||||
HYPRE_Int *ilower, *coord, *dir;
|
||||
|
||||
HYPRE_Int *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_SStructVariable *vartypes;
|
||||
hypre_Index varoffset;
|
||||
HYPRE_Int nvars;
|
||||
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
|
||||
@ -677,6 +682,9 @@ HYPRE_SStructGridAssemble( HYPRE_SStructGrid grid )
|
||||
* Set up vneighbor info
|
||||
*-------------------------------------------------*/
|
||||
|
||||
box = hypre_BoxCreate(ndim);
|
||||
tmp_boxa = hypre_BoxArrayCreate(0, ndim);
|
||||
|
||||
nvneighbors = hypre_TAlloc(HYPRE_Int *, nparts);
|
||||
vneighbors = hypre_TAlloc(hypre_SStructNeighbor **, nparts);
|
||||
|
||||
@ -690,33 +698,35 @@ HYPRE_SStructGridAssemble( HYPRE_SStructGrid grid )
|
||||
|
||||
for (var = 0; var < nvars; var++)
|
||||
{
|
||||
vneighbors[part][var] = hypre_TAlloc(hypre_SStructNeighbor,
|
||||
nneighbors[part]);
|
||||
|
||||
hypre_SStructVariableGetOffset((hypre_SStructVariable) vartypes[var],
|
||||
ndim, varoffset);
|
||||
|
||||
vb = 0;
|
||||
/* Put each new vneighbor box into a BoxArrayArray so we can remove overlap */
|
||||
nbor_boxes = hypre_BoxArrayArrayCreate(nneighbors[part], ndim);
|
||||
fr_roots = hypre_TAlloc(hypre_Index, nneighbors[part]);
|
||||
to_roots = hypre_TAlloc(hypre_Index, nneighbors[part]);
|
||||
hypre_SStructVariableGetOffset((hypre_SStructVariable) vartypes[var], ndim, varoffset);
|
||||
nvneighbors[part][var] = 0;
|
||||
for (b = 0; b < nneighbors[part]; b++)
|
||||
{
|
||||
neighbor = &neighbors[part][b];
|
||||
nbor_offset = nbor_offsets[part][b];
|
||||
vneighbor = &vneighbors[part][var][vb];
|
||||
|
||||
/* set pointers to vneighbor data */
|
||||
box = hypre_SStructNeighborBox(vneighbor);
|
||||
ilower = hypre_SStructNeighborILower(vneighbor);
|
||||
coord = hypre_SStructNeighborCoord(vneighbor);
|
||||
dir = hypre_SStructNeighborDir(vneighbor);
|
||||
/* copy neighbor data into vneighbor */
|
||||
/* Create var-centered vneighbor box from cell-centered 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);
|
||||
/* 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++)
|
||||
{
|
||||
/* 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)) ||
|
||||
((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++;
|
||||
}
|
||||
|
||||
} /* 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 part loop */
|
||||
@ -750,6 +805,9 @@ HYPRE_SStructGridAssemble( HYPRE_SStructGrid grid )
|
||||
hypre_SStructGridNVNeighbors(grid) = nvneighbors;
|
||||
hypre_SStructGridVNeighbors(grid) = vneighbors;
|
||||
|
||||
hypre_BoxArrayDestroy(tmp_boxa);
|
||||
hypre_BoxDestroy(box);
|
||||
|
||||
/*-------------------------------------------------
|
||||
* Assemble the box manager info
|
||||
*-------------------------------------------------*/
|
||||
|
||||
@ -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_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_SStructBoxToNborBox ( hypre_Box *box , hypre_Index index , hypre_Index nbor_index , hypre_Index coord , hypre_Index dir );
|
||||
HYPRE_Int hypre_SStructNborBoxToBox ( hypre_Box *nbor_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_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_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 );
|
||||
|
||||
@ -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_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_SStructBoxToNborBox ( hypre_Box *box , hypre_Index index , hypre_Index nbor_index , hypre_Index coord , hypre_Index dir );
|
||||
HYPRE_Int hypre_SStructNborBoxToBox ( hypre_Box *nbor_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_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_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 );
|
||||
|
||||
@ -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_SStructBoxToNborBox( hypre_Box *box,
|
||||
hypre_Index index,
|
||||
hypre_Index nbor_index,
|
||||
hypre_Index root,
|
||||
hypre_Index nbor_root,
|
||||
hypre_Index coord,
|
||||
hypre_Index dir )
|
||||
{
|
||||
@ -1808,15 +1828,10 @@ hypre_SStructBoxToNborBox( hypre_Box *box,
|
||||
HYPRE_Int *imax = hypre_BoxIMax(box);
|
||||
HYPRE_Int ndim = hypre_BoxNDim(box);
|
||||
hypre_Index nbor_imin, nbor_imax;
|
||||
HYPRE_Int d;
|
||||
|
||||
HYPRE_Int d, nd;
|
||||
|
||||
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];
|
||||
}
|
||||
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++)
|
||||
{
|
||||
@ -1831,10 +1846,31 @@ hypre_SStructBoxToNborBox( hypre_Box *box,
|
||||
* 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_SStructNborBoxToBox( hypre_Box *nbor_box,
|
||||
hypre_Index index,
|
||||
hypre_Index nbor_index,
|
||||
hypre_Index root,
|
||||
hypre_Index nbor_root,
|
||||
hypre_Index coord,
|
||||
hypre_Index dir )
|
||||
{
|
||||
@ -1842,15 +1878,10 @@ hypre_SStructNborBoxToBox( hypre_Box *nbor_box,
|
||||
HYPRE_Int *nbor_imax = hypre_BoxIMax(nbor_box);
|
||||
HYPRE_Int ndim = hypre_BoxNDim(nbor_box);
|
||||
hypre_Index imin, imax;
|
||||
HYPRE_Int d;
|
||||
|
||||
HYPRE_Int d, nd;
|
||||
|
||||
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];
|
||||
}
|
||||
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++)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user