52 if (AMREX_SPACEDIM != 2)
54 amrex::Abort(
"This code only supports 2D (AMREX_SPACEDIM must be 2)");
60 phi_temp[lev]->boxArray() != a_phi[lev]->boxArray() ||
61 phi_temp[lev]->DistributionMap() != a_phi[lev]->DistributionMap())
63 phi_temp[lev] = std::make_unique<amrex::MultiFab>(a_phi[lev]->boxArray(), a_phi[lev]->DistributionMap(),
64 a_phi[lev]->nComp(), a_phi[lev]->nGrow());
67 phi_void[lev]->boxArray() != a_phi[lev]->boxArray() ||
68 phi_void[lev]->DistributionMap() != a_phi[lev]->DistributionMap())
70 phi_void[lev] = std::make_unique<amrex::MultiFab>(a_phi[lev]->boxArray(), a_phi[lev]->DistributionMap(),
71 a_phi[lev]->nComp(), a_phi[lev]->nGrow());
74 bool first_solid =
true;
75 bool first_void =
true;
76 bool any_void =
false;
78 for (
unsigned int p = 0; p <
polygons.size(); p++)
80 std::vector<Set::Vector> polygon =
polygons[p];
81 if (polygon.back() != polygon.front())
84 polygon.push_back(polygon.front());
87 bool is_first = is_void ? first_void : first_solid;
89 for (amrex::MFIter mfi(*a_phi[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
92 amrex::IndexType type = a_phi[lev]->ixType();
93 if (type == amrex::IndexType::TheCellType()) bx = mfi.growntilebox();
94 else if (type == amrex::IndexType::TheNodeType()) bx = mfi.grownnodaltilebox();
96 amrex::Array4<Set::Scalar>
const& phi = a_phi[lev]->array(mfi);
97 amrex::Array4<Set::Scalar>
const& phi_t =
phi_temp[lev]->array(mfi);
98 amrex::Array4<Set::Scalar>
const& phi_v =
phi_void[lev]->array(mfi);
100 std::vector<Set::Vector>
X = polygon;
102 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
106 Set::Scalar min_dist_to_edge = std::numeric_limits<Set::Scalar>::max();
122 for (
unsigned int n = 0; n <
X.size()-1; n++)
130 if ((y1 > x(1)) != (y2 > x(1)))
132 x_cross = x1 + (x(1) - y1) * (x2 - x1) / (y2 - y1);
157 len2 = dx*dx + dy*dy;
158 t = ((px - x1)*dx + (py - y1)*dy) / len2;
172 x_int(0) = x1 +
t*dx;
173 x_int(1) = y1 +
t*dy;
176 dist_to_edge =
dist(x(0), x(1), x_int(0), x_int(1));
177 min_dist_to_edge = std::min(min_dist_to_edge, dist_to_edge);
180 if (num_cross % 2 == 0)
182 min_dist_to_edge = 1*min_dist_to_edge;
185 min_dist_to_edge = -1*min_dist_to_edge;
188 phi_t(i,j,k) = 0.5 * (1.0 - std::tanh(min_dist_to_edge /(std::sqrt(2.0) *
eps)));
192 if (is_void) phi_v(i,j,k) = is_first ? phi_t(i,j,k) : std::max(phi_v(i,j,k), phi_t(i,j,k));
193 else phi(i,j,k) = is_first ? phi_t(i,j,k) : std::max(phi(i,j,k), phi_t(i,j,k));
197 if (is_void) { first_void =
false; any_void =
true; }
198 else first_solid =
false;
205 for (amrex::MFIter mfi(*a_phi[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
208 amrex::IndexType type = a_phi[lev]->ixType();
209 if (type == amrex::IndexType::TheCellType()) bx = mfi.growntilebox();
210 else if (type == amrex::IndexType::TheNodeType()) bx = mfi.grownnodaltilebox();
212 amrex::Array4<Set::Scalar>
const& phi = a_phi[lev]->array(mfi);
213 amrex::Array4<Set::Scalar>
const& phi_v =
phi_void[lev]->array(mfi);
215 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
217 phi(i,j,k) = phi(i,j,k) * (1.0 - phi_v(i,j,k));
224 for (amrex::MFIter mfi(*a_phi[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
227 amrex::IndexType type = a_phi[lev]->ixType();
228 if (type == amrex::IndexType::TheCellType()) bx = mfi.growntilebox();
229 else if (type == amrex::IndexType::TheNodeType()) bx = mfi.grownnodaltilebox();
231 amrex::Array4<Set::Scalar>
const& phi = a_phi[lev]->array(mfi);
233 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
235 phi(i,j,k) = 1 - phi(i,j,k);
243 std::string filename;
248 pp.
forbid(
"filename",
"use file.name instead");
280 std::ifstream datafile(filename);
282 if (datafile.is_open())
285 bool have_prev_obj_num =
false;
288 while (getline(datafile, line))
290 std::istringstream in(line);
292 std::string strx, stry, strz, strObjNum;
293 in >> strx >> stry >> strz;
295 Set::Scalar x = (std::stod(strx) * unit).normalized_value();
296 Set::Scalar y = (std::stod(stry) * unit).normalized_value();
297 #if AMREX_SPACEDIM > 2
298 Set::Scalar z = (std::stod(strz) * unit).normalized_value();
302 Set::Scalar ObjNum = have_prev_obj_num ? prev_obj_num : 0.0;
303 if (in >> strObjNum) ObjNum = std::stod(strObjNum);
318 X[0] = cx + x_shifted * cos_t - y_shifted * sin_t;
319 X[1] = cy + x_shifted * sin_t + y_shifted * cos_t;
324 if (!have_prev_obj_num || std::abs(ObjNum - prev_obj_num) > value.
objnum_threshold)
326 value.
polygons.push_back(std::vector<Set::Vector>());
328 have_prev_obj_num =
true;
329 prev_obj_num = ObjNum;
347 "'invert' must have one entry per polygon: expected ", value.
polygons.size(),
348 " but got ", value.
invert.size());