Skip to content

Commit

Permalink
Fix EB data inconsistency when fixing small cells and multiple cuts (A…
Browse files Browse the repository at this point in the history
…MReX-Codes#2943)

## Summary

For consistency, we need to call the function that zeros out the level
set even if that box does not have any small cells or multiple cuts.
This is because a node could exist in multiple boxes. Furthermore, a
covered cell or covered face may have a node with a level set < 0.

## Additional background

This is usually not an issue. However, in WarpX, we use the level set to
decide whether a node is an unknown in the linear system. The
inconsistency makes the solver fail in some cases.
  • Loading branch information
WeiqunZhang committed Oct 14, 2022
1 parent 9c2264b commit 975b830
Showing 1 changed file with 77 additions and 78 deletions.
155 changes: 77 additions & 78 deletions Src/EB/AMReX_EB2_3D_C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -853,90 +853,89 @@ void build_cells (Box const& bx, Array4<EBCellFlag> const& cell,
nsmallcells += hp[0];
nmulticuts += hp[1];

Box const& nbxg1 = amrex::surroundingNodes(bxg1);
Box const& bxg1x = amrex::surroundingNodes(bxg1,0);
Box const& bxg1y = amrex::surroundingNodes(bxg1,1);
Box const& bxg1z = amrex::surroundingNodes(bxg1,2);
AMREX_HOST_DEVICE_FOR_3D(nbxg1, i, j, k,
{
if (levset(i,j,k) < Real(0.0)) {
bool zero_levset = false;
if (bxg1.contains(i-1,j-1,k-1)
&& cell(i-1,j-1,k-1).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i ,j-1,k-1)
&& cell(i ,j-1,k-1).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i-1,j ,k-1)
&& cell(i-1,j ,k-1).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i ,j ,k-1)
&& cell(i ,j ,k-1).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i-1,j-1,k )
&& cell(i-1,j-1,k ).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i ,j-1,k )
&& cell(i ,j-1,k ).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i-1,j ,k )
&& cell(i-1,j ,k ).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i ,j ,k )
&& cell(i ,j ,k ).isCovered()) {
zero_levset = true;
} else if (bxg1x.contains(i ,j-1,k-1)
&& fx(i ,j-1,k-1) == Type::covered) {
zero_levset = true;
} else if (bxg1x.contains(i ,j ,k-1)
&& fx(i ,j ,k-1) == Type::covered) {
zero_levset = true;
} else if (bxg1x.contains(i ,j-1,k )
&& fx(i ,j-1,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1x.contains(i ,j ,k )
&& fx(i ,j ,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1y.contains(i-1,j ,k-1)
&& fy(i-1,j ,k-1) == Type::covered) {
zero_levset = true;
} else if (bxg1y.contains(i ,j ,k-1)
&& fy(i ,j ,k-1) == Type::covered) {
zero_levset = true;
} else if (bxg1y.contains(i-1,j ,k )
&& fy(i-1,j ,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1y.contains(i ,j ,k )
&& fy(i ,j ,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1z.contains(i-1,j-1,k )
&& fz(i-1,j-1,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1z.contains(i ,j-1,k )
&& fz(i ,j-1,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1z.contains(i-1,j ,k )
&& fz(i-1,j ,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1z.contains(i ,j ,k )
&& fz(i ,j ,k ) == Type::covered) {
zero_levset = true;
}
if (zero_levset) {
levset(i,j,k) = Real(0.0);
}
}
});

if (nsmallcells > 0 || nmulticuts > 0) {
if (!cover_multiple_cuts && nmulticuts > 0) {
amrex::Abort("amrex::EB2::build_cells: multi-cuts not supported");
}
Box const& nbxg1 = amrex::surroundingNodes(bxg1);
Box const& bxg1x = amrex::surroundingNodes(bxg1,0);
Box const& bxg1y = amrex::surroundingNodes(bxg1,1);
Box const& bxg1z = amrex::surroundingNodes(bxg1,2);
AMREX_HOST_DEVICE_FOR_3D(nbxg1, i, j, k,
{
if (levset(i,j,k) < Real(0.0)) {
bool zero_levset = false;
if (bxg1.contains(i-1,j-1,k-1)
&& cell(i-1,j-1,k-1).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i ,j-1,k-1)
&& cell(i ,j-1,k-1).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i-1,j ,k-1)
&& cell(i-1,j ,k-1).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i ,j ,k-1)
&& cell(i ,j ,k-1).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i-1,j-1,k )
&& cell(i-1,j-1,k ).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i ,j-1,k )
&& cell(i ,j-1,k ).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i-1,j ,k )
&& cell(i-1,j ,k ).isCovered()) {
zero_levset = true;
} else if (bxg1.contains(i ,j ,k )
&& cell(i ,j ,k ).isCovered()) {
zero_levset = true;
} else if (cover_multiple_cuts) {
if (bxg1x.contains(i ,j-1,k-1)
&& fx(i ,j-1,k-1) == Type::covered) {
zero_levset = true;
} else if (bxg1x.contains(i ,j ,k-1)
&& fx(i ,j ,k-1) == Type::covered) {
zero_levset = true;
} else if (bxg1x.contains(i ,j-1,k )
&& fx(i ,j-1,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1x.contains(i ,j ,k )
&& fx(i ,j ,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1y.contains(i-1,j ,k-1)
&& fy(i-1,j ,k-1) == Type::covered) {
zero_levset = true;
} else if (bxg1y.contains(i ,j ,k-1)
&& fy(i ,j ,k-1) == Type::covered) {
zero_levset = true;
} else if (bxg1y.contains(i-1,j ,k )
&& fy(i-1,j ,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1y.contains(i ,j ,k )
&& fy(i ,j ,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1z.contains(i-1,j-1,k )
&& fz(i-1,j-1,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1z.contains(i ,j-1,k )
&& fz(i ,j-1,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1z.contains(i-1,j ,k )
&& fz(i-1,j ,k ) == Type::covered) {
zero_levset = true;
} else if (bxg1z.contains(i ,j ,k )
&& fz(i ,j ,k ) == Type::covered) {
zero_levset = true;
}
}
if (zero_levset) {
levset(i,j,k) = Real(0.0);
}
}
});
return;
} else {
set_connection_flags(bx, bxg1, cell, ctmp, fx, fy, fz);
}

set_connection_flags(bx, bxg1, cell, ctmp, fx, fy, fz);
}

void set_connection_flags (Box const& bx,
Expand Down

0 comments on commit 975b830

Please sign in to comment.