Skip to content

Commit 54941f6

Browse files
committed
Cleanup and address clang complication error.
Signed-off-by: apradhana <andre.pradhana@gmail.com>
1 parent 9bb6923 commit 54941f6

1 file changed

Lines changed: 135 additions & 133 deletions

File tree

openvdb/openvdb/unittest/TestPoissonSolver.cc

Lines changed: 135 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -490,16 +490,23 @@ using namespace openvdb;
490490

491491
// 0 Neumann pressure, meaning Dirichlet velocity on its normal face.
492492
// 1 interior pressure dofs.
493-
// 4 Dirichlet pressure. In this setup it's on the right. It means that it's not a solid collider or an open channel.
493+
// 4 Dirichlet pressure, meaning it's not a solid collider, i.e. an open channel.
494494
class SmokeSolver {
495495
public:
496-
SmokeSolver(float const voxelSize) { init(voxelSize); }
497-
498-
void init(float const vs)
496+
SmokeSolver(float const voxelSize, math::Coord corner) :
497+
mVoxelSize(voxelSize),
498+
mXform(math::Transform::createLinearTransform(voxelSize))
499499
{
500-
mXform = math::Transform::createLinearTransform(mVoxelSize);
500+
assert(corner[0] > 1 && corner[1] > 1 && corner[2] > 1);
501+
502+
init(corner);
503+
}
504+
505+
void init(math::Coord corner) {
506+
float xDim = static_cast<float>(corner[0]);
507+
float yDim = static_cast<float>(corner[1]);
508+
float zDim = static_cast<float>(corner[2]);
501509

502-
int xDim = 3; int yDim = 15; int zDim = 17;
503510
mMinBBox = Vec3s(0.f, 0.f, 0.f);
504511
mMaxBBox = Vec3s(xDim * mVoxelSize, yDim * mVoxelSize, zDim * mVoxelSize);
505512
mMinIdx = mXform->worldToIndexNodeCentered(mMinBBox);
@@ -512,73 +519,68 @@ class SmokeSolver {
512519
initDivGrids();
513520
}
514521

515-
// In the Flip Example class, this is VelocityBCCorrectionOp
516-
void applyDirichletVelocity() {
517-
auto flagsAcc = mFlags->getAccessor();
518-
auto vAcc = mVCurr->getAccessor();
519-
for (auto iter = mFlags->beginValueOn(); iter; ++iter) {
520-
math::Coord ijk = iter.getCoord();
521-
math::Coord im1jk = ijk.offsetBy(-1, 0, 0);
522-
math::Coord ijm1k = ijk.offsetBy(0, -1, 0);
523-
math::Coord ijkm1 = ijk.offsetBy(0, 0, -1);
524-
525-
int flag = flagsAcc.getValue(ijk);
526-
int flagim1jk = flagsAcc.getValue(im1jk);
527-
int flagijm1k = flagsAcc.getValue(ijm1k);
528-
int flagijkm1 = flagsAcc.getValue(ijkm1);
529-
// I'm an interior pressure and I need to check if any of my neighbor is Neumann
530-
if (flag == 1)
531-
{
532-
if (flagim1jk == 0)
533-
{
534-
auto cv = vAcc.getValue(ijk);
535-
Vec3f newVel(0, cv[1], cv[2]);
536-
vAcc.setValue(ijk, newVel);
537-
}
522+
void pressureProjection() {
523+
using TreeType = FloatTree;
524+
using ValueType = TreeType::ValueType;
525+
using PCT = openvdb::math::pcg::JacobiPreconditioner<openvdb::tools::poisson::LaplacianMatrix>;
538526

539-
if (flagijm1k == 0) {
540-
auto cv = vAcc.getValue(ijk);
541-
Vec3f newVel(cv[0], 0, cv[2]);
542-
vAcc.setValue(ijk, newVel);
527+
BoundaryOp bop(mFlags, mVCurr, mVoxelSize);
528+
util::NullInterrupter interrupter;
543529

544-
}
530+
const double epsilon = math::Delta<ValueType>::value();
545531

546-
if (flagijkm1 == 0) {
547-
auto cv = vAcc.getValue(ijk);
548-
Vec3f newVel(cv[0], cv[1], 0);
549-
vAcc.setValue(ijk, newVel);
550-
}
532+
mState = math::pcg::terminationDefaults<ValueType>();
533+
mState.iterations = 100;
534+
mState.relativeError = mState.absoluteError = epsilon;
535+
FloatTree::Ptr fluidPressure = tools::poisson::solveWithBoundaryConditionsAndPreconditioner<PCT>(
536+
mDivBefore->tree(), mInteriorPressure->tree(), bop, mState, interrupter, /*staggered=*/true);
551537

552-
} else if (flag == 0) { // I'm a Neumann pressure and I need if any of my Neighbor is interior
553-
if (flagim1jk == 1)
554-
{
555-
auto cv = vAcc.getValue(ijk);
556-
Vec3f newVel(0, cv[1], cv[2]);
557-
vAcc.setValue(ijk, newVel);
558-
}
538+
FloatGrid::Ptr fluidPressureGrid = FloatGrid::create(fluidPressure);
539+
fluidPressureGrid->setTransform(mXform);
540+
mPressure = fluidPressureGrid->copy();
541+
mPressure->setName("pressure");
542+
}
559543

560-
if (flagijm1k == 1) {
561-
auto cv = vAcc.getValue(ijk);
562-
Vec3f newVel(cv[0], 0, cv[2]);
563-
vAcc.setValue(ijk, newVel);
564-
}
544+
void subtractPressureGradFromVel() {
545+
auto vCurrAcc = mVCurr->getAccessor();
546+
auto pressureAcc = mPressure->getConstAccessor();
547+
auto flagsAcc = mFlags->getConstAccessor();
548+
for (auto iter = mVCurr->beginValueOn(); iter; ++iter) {
549+
math::Coord ijk = iter.getCoord();
550+
math::Coord im1jk = ijk.offsetBy(-1, 0, 0);
551+
math::Coord ijm1k = ijk.offsetBy(0, -1, 0);
552+
math::Coord ijkm1 = ijk.offsetBy(0, 0, -1);
565553

566-
if (flagijkm1 == 1) {
567-
auto cv = vAcc.getValue(ijk);
568-
Vec3f newVel(cv[0], cv[1], 0);
569-
vAcc.setValue(ijk, newVel);
554+
// Only updates velocity if it is a face of fluid cell
555+
bool neighborsAFluidCell = flagsAcc.getValue(ijk) == 1 || flagsAcc.getValue(im1jk) == 1 || flagsAcc.getValue(ijm1k) == 1 || flagsAcc.getValue(ijkm1) == 1;
556+
if (neighborsAFluidCell) {
557+
Vec3s gradijk;
558+
gradijk[0] = pressureAcc.getValue(ijk) - pressureAcc.getValue(ijk.offsetBy(-1, 0, 0));
559+
gradijk[1] = pressureAcc.getValue(ijk) - pressureAcc.getValue(ijk.offsetBy(0, -1, 0));
560+
gradijk[2] = pressureAcc.getValue(ijk) - pressureAcc.getValue(ijk.offsetBy(0, 0, -1));
561+
auto val = vCurrAcc.getValue(ijk) - gradijk * mVoxelSize;
562+
vCurrAcc.setValue(ijk, val);
570563
}
571-
}
572564
}
565+
566+
applyDirichletVelocity(); // VERY IMPORTANT
567+
}
568+
569+
float computeDivergence(FloatGrid::Ptr& divGrid, const Vec3SGrid::Ptr vecGrid) {
570+
divGrid = tools::divergence(*vecGrid);
571+
divGrid->tree().topologyIntersection(mInteriorPressure->tree());
572+
float div = computeLInfinity(*divGrid);
573+
return div;
573574
}
574575

576+
private:
575577
struct BoundaryOp {
576578
BoundaryOp(Int32Grid::ConstPtr flags,
577-
Vec3SGrid::ConstPtr dirichletVelocity,
578-
float const voxelSize) :
579-
flags(flags),
580-
dirichletVelocity(dirichletVelocity),
581-
voxelSize(voxelSize) {}
579+
Vec3SGrid::ConstPtr dirichletVelocity,
580+
float const voxelSize) :
581+
flags(flags),
582+
dirichletVelocity(dirichletVelocity),
583+
voxelSize(voxelSize) {}
582584

583585
void operator()(const openvdb::Coord& ijk,
584586
const openvdb::Coord& neighbor,
@@ -593,7 +595,6 @@ class SmokeSolver {
593595

594596
if (isNeumannPressure) {
595597
double delta = 0.0;
596-
// Neumann pressure from bbox
597598
if (neighbor.x() + 1 == ijk.x() /* left x-face */) {
598599
delta += vNgbr[0];
599600
}
@@ -619,7 +620,7 @@ class SmokeSolver {
619620
} else if (isDirichletPressure) {
620621
diagonal -= 1.0;
621622
source -= dirichletBC;
622-
#if 0 // supposedly the same as the two lines above
623+
#if 0 // TODO: double check this logic
623624
// Dirichlet pressure
624625
if (neighbor.x() + 1 == ijk.x() /* left x-face */) {
625626
diagonal -= 1.0;
@@ -654,67 +655,72 @@ class SmokeSolver {
654655
float voxelSize;
655656
};
656657

657-
void subtractPressureGradFromVel() {
658-
auto vCurrAcc = mVCurr->getAccessor();
659-
auto pressureAcc = mPressure->getConstAccessor();
660-
auto flagsAcc = mFlags->getConstAccessor();
661-
for (auto iter = mVCurr->beginValueOn(); iter; ++iter) {
662-
math::Coord ijk = iter.getCoord();
663-
math::Coord im1jk = ijk.offsetBy(-1, 0, 0);
664-
math::Coord ijm1k = ijk.offsetBy(0, -1, 0);
665-
math::Coord ijkm1 = ijk.offsetBy(0, 0, -1);
666-
667-
// Only updates velocity if it is a face of fluid cell
668-
if (flagsAcc.getValue(ijk) == 1 ||
669-
flagsAcc.getValue(im1jk) == 1 ||
670-
flagsAcc.getValue(ijm1k) == 1 ||
671-
flagsAcc.getValue(ijkm1) == 1) {
672-
Vec3s gradijk;
673-
gradijk[0] = pressureAcc.getValue(ijk) - pressureAcc.getValue(ijk.offsetBy(-1, 0, 0));
674-
gradijk[1] = pressureAcc.getValue(ijk) - pressureAcc.getValue(ijk.offsetBy(0, -1, 0));
675-
gradijk[2] = pressureAcc.getValue(ijk) - pressureAcc.getValue(ijk.offsetBy(0, 0, -1));
676-
auto val = vCurrAcc.getValue(ijk) - gradijk * mVoxelSize;
677-
vCurrAcc.setValue(ijk, val);
678-
}
679-
}
658+
// In the Flip Example class, this is VelocityBCCorrectionOp
659+
void applyDirichletVelocity() {
660+
auto flagsAcc = mFlags->getAccessor();
661+
auto vAcc = mVCurr->getAccessor();
662+
for (auto iter = mFlags->beginValueOn(); iter; ++iter) {
663+
math::Coord ijk = iter.getCoord();
664+
math::Coord im1jk = ijk.offsetBy(-1, 0, 0);
665+
math::Coord ijm1k = ijk.offsetBy(0, -1, 0);
666+
math::Coord ijkm1 = ijk.offsetBy(0, 0, -1);
680667

681-
applyDirichletVelocity(); // VERY IMPORTANT
682-
}
668+
int flag = flagsAcc.getValue(ijk);
669+
int flagim1jk = flagsAcc.getValue(im1jk);
670+
int flagijm1k = flagsAcc.getValue(ijm1k);
671+
int flagijkm1 = flagsAcc.getValue(ijkm1);
672+
673+
if (flag == 1) { // I'm an interior pressure and I need to check if any of my neighbor is Neumann
674+
if (flagim1jk == 0) {
675+
auto cv = vAcc.getValue(ijk);
676+
Vec3f newVel(0, cv[1], cv[2]);
677+
vAcc.setValue(ijk, newVel);
678+
}
683679

684-
void pressureProjection() {
685-
using TreeType = FloatTree;
686-
using ValueType = TreeType::ValueType;
687-
using PCT = openvdb::math::pcg::JacobiPreconditioner<openvdb::tools::poisson::LaplacianMatrix>;
680+
if (flagijm1k == 0) {
681+
auto cv = vAcc.getValue(ijk);
682+
Vec3f newVel(cv[0], 0, cv[2]);
683+
vAcc.setValue(ijk, newVel);
684+
}
688685

689-
BoundaryOp bop(mFlags, mVCurr, mVoxelSize);
690-
util::NullInterrupter interrupter;
686+
if (flagijkm1 == 0) {
687+
auto cv = vAcc.getValue(ijk);
688+
Vec3f newVel(cv[0], cv[1], 0);
689+
vAcc.setValue(ijk, newVel);
690+
}
691691

692-
const double epsilon = math::Delta<ValueType>::value();
692+
} else if (flag == 0) { // I'm a Neumann pressure and I need if any of my Neighbor is interior
693+
if (flagim1jk == 1) {
694+
auto cv = vAcc.getValue(ijk);
695+
Vec3f newVel(0, cv[1], cv[2]);
696+
vAcc.setValue(ijk, newVel);
697+
}
693698

694-
mState = math::pcg::terminationDefaults<ValueType>();
695-
mState.iterations = 100;
696-
mState.relativeError = mState.absoluteError = epsilon;
697-
FloatTree::Ptr fluidPressure = tools::poisson::solveWithBoundaryConditionsAndPreconditioner<PCT>(
698-
mDivBefore->tree(), mInteriorPressure->tree(), bop, mState, interrupter, /*staggered=*/true);
699+
if (flagijm1k == 1) {
700+
auto cv = vAcc.getValue(ijk);
701+
Vec3f newVel(cv[0], 0, cv[2]);
702+
vAcc.setValue(ijk, newVel);
703+
}
699704

700-
FloatGrid::Ptr fluidPressureGrid = FloatGrid::create(fluidPressure);
701-
fluidPressureGrid->setTransform(mXform);
702-
mPressure = fluidPressureGrid->copy();
703-
mPressure->setName("pressure");
705+
if (flagijkm1 == 1) {
706+
auto cv = vAcc.getValue(ijk);
707+
Vec3f newVel(cv[0], cv[1], 0);
708+
vAcc.setValue(ijk, newVel);
709+
}
710+
}
711+
}
704712
}
705713

706714
template<class GridType>
707715
typename GridType::Ptr
708-
initGridBgAndName(typename GridType::ValueType background, std::string name)
709-
{
716+
initGridBgAndName(typename GridType::ValueType background, std::string name) {
710717
typename GridType::Ptr grid = GridType::create(background);
711718
grid->setTransform(mXform);
712719
grid->setName(name);
713720
return grid;
714721
}
715722

716-
void initFlags()
717-
{
723+
void initFlags() {
718724
mFlags = initGridBgAndName<Int32Grid>(0, "flags");
719725
mFlags->denseFill(CoordBBox(mMinIdx, mMaxIdx), /* value = */ 1, /* active = */ true);
720726

@@ -740,26 +746,6 @@ class SmokeSolver {
740746
mDivAfter = initGridBgAndName<FloatGrid>(0.f, "div_after");
741747
}
742748

743-
float computeLInfinity(const FloatGrid& grid) {
744-
float ret = 0.f;
745-
auto acc = grid.getConstAccessor();
746-
for (auto iter = grid.beginValueOn(); iter; ++iter) {
747-
math::Coord ijk = iter.getCoord();
748-
auto val = acc.getValue(ijk);
749-
if (std::abs(val) > std::abs(ret)) {
750-
ret = val;
751-
}
752-
}
753-
return ret;
754-
}
755-
756-
float computeDivergence(FloatGrid::Ptr& divGrid, const Vec3SGrid::Ptr vecGrid, const std::string& suffix) {
757-
divGrid = tools::divergence(*vecGrid);
758-
divGrid->tree().topologyIntersection(mInteriorPressure->tree());
759-
float div = computeLInfinity(*divGrid);
760-
return div;
761-
}
762-
763749
void initVCurr()
764750
{
765751
mVCurr = initGridBgAndName<Vec3SGrid>(Vec3s::zero(), "vel_curr");
@@ -768,7 +754,7 @@ class SmokeSolver {
768754

769755
auto flagsAcc = mFlags->getConstAccessor();
770756
auto velAcc = mVCurr->getAccessor();
771-
const float hv = .5f * mXform->voxelSize()[0]; // half of voxel size
757+
const float hv = .5f * static_cast<float>(mXform->voxelSize()[0]); // half of voxel size
772758
for (auto iter = mVCurr->beginValueOn(); iter; ++iter) {
773759
auto ijk = iter.getCoord();
774760
Vec3f center = mXform->indexToWorld(ijk);
@@ -797,6 +783,20 @@ class SmokeSolver {
797783
}
798784
}
799785

786+
float computeLInfinity(const FloatGrid& grid) {
787+
float ret = 0.f;
788+
auto acc = grid.getConstAccessor();
789+
for (auto iter = grid.beginValueOn(); iter; ++iter) {
790+
math::Coord ijk = iter.getCoord();
791+
auto val = acc.getValue(ijk);
792+
if (std::abs(val) > std::abs(ret)) {
793+
ret = val;
794+
}
795+
}
796+
return ret;
797+
}
798+
799+
public:
800800
bool mVERBOSE = false;
801801

802802
float mVoxelSize = 0.1f;
@@ -821,9 +821,11 @@ TEST_F(TestPoissonSolver, testRemoveDivergence)
821821
{
822822
using namespace openvdb;
823823

824-
SmokeSolver smoke(0.1f);
824+
float voxelSize = 0.1f;
825+
math::Coord topRightCorner(3, 15, 17);
826+
SmokeSolver smoke(voxelSize, topRightCorner);
825827

826-
float divBefore = smoke.computeDivergence(smoke.mDivBefore, smoke.mVCurr, "before");
828+
float divBefore = smoke.computeDivergence(smoke.mDivBefore, smoke.mVCurr);
827829
EXPECT_NEAR(divBefore, -39.425, 1.e-4f);
828830

829831
// Make the velocity divergence free by solving Poisson Equation and subtracting the pressure gradient
@@ -836,6 +838,6 @@ TEST_F(TestPoissonSolver, testRemoveDivergence)
836838
EXPECT_TRUE(smoke.mState.relativeError < 1.e-5f);
837839
EXPECT_TRUE(smoke.mState.absoluteError < 1.e-3f);
838840

839-
float divAfter = smoke.computeDivergence(smoke.mDivAfter, smoke.mVCurr, "after");
840-
EXPECT_TRUE(divAfter < 1.e-3f);
841+
float divAfter = smoke.computeDivergence(smoke.mDivAfter, smoke.mVCurr);
842+
EXPECT_LT(divAfter, 1.e-3f);
841843
}

0 commit comments

Comments
 (0)