JET_END_TEST_F JET_BEGIN_TEST_F(FmmLevelSetSolver2, Extrapolate) { Size2 size(160, 120); Vector2D gridSpacing(1.0/size.x, 1.0/size.x); double maxDistance = 20.0 * gridSpacing.x; FmmLevelSetSolver2 solver; CellCenteredScalarGrid2 sdf(size, gridSpacing); CellCenteredScalarGrid2 input(size, gridSpacing); CellCenteredScalarGrid2 output(size, gridSpacing); sdf.fill([&](const Vector2D& x) { return (x - Vector2D(0.75, 0.5)).length() - 0.3; }); input.fill([&](const Vector2D& x) { if ((x - Vector2D(0.75, 0.5)).length() <= 0.3) { double p = 10.0 * kPiD; return 0.5 * 0.25 * std::sin(p * x.x) * std::sin(p * x.y); } else { return 0.0; } }); solver.extrapolate(input, sdf, maxDistance, &output); saveData(sdf.constDataAccessor(), "sdf_#grid2,iso.npy"); saveData(input.constDataAccessor(), "input_#grid2.npy"); saveData(output.constDataAccessor(), "output_#grid2.npy"); }
JET_END_TEST_F JET_BEGIN_TEST_F(FmmLevelSetSolver2, Reinitialize) { CellCenteredScalarGrid2 sdf(160, 120), temp(160, 120); FmmLevelSetSolver2 solver; // Starting from constant field sdf.fill([](const Vector2D& x) { return 1.0; }); saveData(sdf.constDataAccessor(), "constant0_#grid2,iso.npy"); solver.reinitialize(sdf, 160.0, &temp); saveData(temp.constDataAccessor(), "constant1_#grid2,iso.npy"); // Starting from SDF field sdf.fill([](const Vector2D& x) { return (x - Vector2D(80, 80)).length() - 32.0; }); saveData(sdf.constDataAccessor(), "sdf0_#grid2,iso.npy"); solver.reinitialize(sdf, 160.0, &temp); saveData(temp.constDataAccessor(), "sdf1_#grid2,iso.npy"); // Starting from scaled SDF field sdf.fill([](const Vector2D& x) { double r = (x - Vector2D(80, 80)).length() - 32.0; return 2.0 * r; }); saveData(sdf.constDataAccessor(), "scaled0_#grid2,iso.npy"); solver.reinitialize(sdf, 160.0, &temp); saveData(temp.constDataAccessor(), "scaled1_#grid2,iso.npy"); // Starting from scaled SDF field sdf.fill([](const Vector2D& x) { double r = (x - Vector2D(80, 80)).length() - 32.0; return (r < 0.0) ? -0.5 : 0.5; }); saveData(sdf.constDataAccessor(), "unit_step0_#grid2,iso.npy"); solver.reinitialize(sdf, 160.0, &temp); saveData(temp.constDataAccessor(), "unit_step1_#grid2,iso.npy"); }
void LevelSetLiquidSolver2::extrapolateVelocityToAir(double currentCfl) { auto sdf = signedDistanceField(); auto vel = gridSystemData()->velocity(); auto u = vel->uAccessor(); auto v = vel->vAccessor(); auto uPos = vel->uPosition(); auto vPos = vel->vPosition(); Array2<char> uMarker(u.size()); Array2<char> vMarker(v.size()); uMarker.parallelForEachIndex([&](size_t i, size_t j) { if (isInsideSdf(sdf->sample(uPos(i, j)))) { uMarker(i, j) = 1; } else { uMarker(i, j) = 0; u(i, j) = 0.0; } }); vMarker.parallelForEachIndex([&](size_t i, size_t j) { if (isInsideSdf(sdf->sample(vPos(i, j)))) { vMarker(i, j) = 1; } else { vMarker(i, j) = 0; v(i, j) = 0.0; } }); const Vector2D gridSpacing = sdf->gridSpacing(); const double h = std::max(gridSpacing.x, gridSpacing.y); const double maxDist = std::max(2.0 * currentCfl, _minReinitializeDistance) * h; JET_INFO << "Max velocity extrapolation distance: " << maxDist; FmmLevelSetSolver2 fmmSolver; fmmSolver.extrapolate(*vel, *sdf, maxDist, vel.get()); applyBoundaryCondition(); }