Commit e8082be5 authored by Nghia Truong's avatar Nghia Truong

ENH: Rewrite SPH fluid examples, adding the new multiple fluids example

parent 1e61004e
Pipeline #142276 passed with stage
......@@ -22,6 +22,7 @@
#include "imstkSimulationManager.h"
#include "imstkSPHObject.h"
#include "imstkSPHSolver.h"
#include "imstkSPHModel.h"
using namespace imstk;
......@@ -91,7 +92,7 @@ generateBoxShapeFluid(const double particleRadius)
return particles;
}
#if SCENE_ID == 3
#if (SCENE_ID == 3) || (SCENE_ID == 4)
StdVectorOfVec3d getBunny(); // Defined in Bunny.cpp
#endif
///
......@@ -102,13 +103,13 @@ generateBunnyShapeFluid(const double particleRadius)
{
LOG_IF(FATAL, (std::abs(particleRadius - 0.08) > 1e-6)) << "Particle radius for this scene must be 0.08";
StdVectorOfVec3d particles;
#if SCENE_ID == 3
#if (SCENE_ID == 3) || (SCENE_ID == 4)
particles = getBunny();
#endif
return particles;
}
std::shared_ptr<SPHObject>
std::vector<std::shared_ptr<SPHObject>>
generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
{
StdVectorOfVec3d particles;
......@@ -121,11 +122,20 @@ generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
particles = generateBoxShapeFluid(particleRadius);
break;
case 3:
case 4:
particles = generateBunnyShapeFluid(particleRadius);
break;
default:
LOG(FATAL) << "Invalid scene index";
}
if (SCENE_ID == 4)
{
const double translation = 3.0;
for (size_t i = 0; i < particles.size(); ++i)
{
particles[i] -= Vec3d(translation, 0, 0);
}
}
LOG(INFO) << "Number of particles: " << particles.size();
......@@ -134,7 +144,7 @@ generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
fluidGeometry->initialize(particles);
// Create a fluids object
auto fluidObj = std::make_shared<SPHObject>("Sphere");
auto fluidObj1 = std::make_shared<SPHObject>("FluidObj1");
// Create a visual model
auto fluidVisualModel = std::make_shared<VisualModel>(fluidGeometry);
......@@ -149,33 +159,88 @@ generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
// configure model
auto sphParams = std::make_shared<SPHModelConfig>(particleRadius);
sphParams->m_bNormalizeDensity = true;
sphParams->m_normalizeDensity = true;
if (SCENE_ID == 2) // highly viscous fluid
{
sphParams->m_kernelOverParticleRadiusRatio = 6.0;
sphParams->m_viscosityCoeff = 0.5;
sphParams->m_surfaceTensionStiffness = 5.0;
sphParams->m_fluidViscosityConstant = 0.5;
sphParams->m_surfaceTensionConstant = 5.0;
}
else if (SCENE_ID == 3 || SCENE_ID == 4) // bunny-shaped fluid
{
sphParams->m_frictionBoundaryConstant = 0.3;
}
if (SCENE_ID == 3) // bunny-shaped fluid
if (SCENE_ID == 4) // multiple fluid
{
sphParams->m_frictionBoundary= 0.3;
sphParams->m_restDensity = 5000;
sphParams->m_surfaceTensionConstant = 0.5;
}
sphModel->configure(sphParams);
sphModel->setTimeStepSizeType(TimeSteppingType::realTime);
// Add the component models
fluidObj->addVisualModel(fluidVisualModel);
fluidObj->setCollidingGeometry(fluidGeometry);
fluidObj->setDynamicalModel(sphModel);
fluidObj->setPhysicsGeometry(fluidGeometry); // TODO: Look into API duplication and resulting conflicts
scene->addSceneObject(fluidObj);
fluidObj1->addVisualModel(fluidVisualModel);
fluidObj1->setCollidingGeometry(fluidGeometry);
fluidObj1->setDynamicalModel(sphModel);
fluidObj1->setPhysicsGeometry(fluidGeometry); // TODO: Look into API duplication and resulting conflicts
scene->addSceneObject(fluidObj1);
// Configure the solver
auto sphSolver = std::make_shared<SPHSolver>();
sphSolver->setSPHObject(fluidObj);
sphSolver->addSPHObject(fluidObj1);
scene->addNonlinearSolver(sphSolver);
return fluidObj;
std::vector<std::shared_ptr<SPHObject>> fluids = { fluidObj1 };
if (SCENE_ID == 4) // multiple fluid
{
auto particlesDup = particles;
const double translation = 3.0;
for (size_t i = 0; i < particlesDup.size(); ++i)
{
particlesDup[i] += Vec3d(translation * 2.0, 0, 0);
}
// Create a geometry object
auto fluidGeometry2 = std::make_shared<PointSet>();
fluidGeometry2->initialize(particlesDup);
// Create a fluids object
auto fluidObj2 = std::make_shared<SPHObject>("FluidObj2");
// Create a visiual model
auto fluidVisualModel2 = std::make_shared<VisualModel>(fluidGeometry2);
auto fluidMaterial2 = std::make_shared<RenderMaterial>();
fluidMaterial2->setColor(Color::Red);
fluidMaterial2->setSphereGlyphSize(particleRadius);
fluidVisualModel2->setRenderMaterial(fluidMaterial2);
// Create a physics model
auto sphModel2 = std::make_shared<SPHModel>();
sphModel2->setModelGeometry(fluidGeometry2);
// configure model
auto sphParams2 = std::make_shared<SPHModelConfig>(particleRadius);
sphParams2->m_normalizeDensity = true;
sphParams2->m_frictionBoundaryConstant = 0.3;
sphParams2->m_restDensity = 1000;
sphModel2->configure(sphParams2);
sphModel2->setTimeStepSizeType(TimeSteppingType::realTime);
// Add the component models
fluidObj2->addVisualModel(fluidVisualModel2);
fluidObj2->setCollidingGeometry(fluidGeometry2);
fluidObj2->setDynamicalModel(sphModel2);
fluidObj2->setPhysicsGeometry(fluidGeometry2); // TODO: Look into API duplication and resulting conflicts
scene->addSceneObject(fluidObj2);
fluids.push_back(fluidObj2);
// Configure the solver
sphSolver->addSPHObject(fluidObj2);
}
return fluids;
}
This diff is collapsed.
###########################################################################
#
# Copyright (c) Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
###########################################################################
project(Example-SPHFluid-MultipleFluids)
#-----------------------------------------------------------------------------
# Create executable
#-----------------------------------------------------------------------------
add_executable(${PROJECT_NAME} SPHFluid-MultipleFluids.cpp Bunny.cpp)
#-----------------------------------------------------------------------------
# Link libraries to executable
#-----------------------------------------------------------------------------
target_link_libraries(${PROJECT_NAME} SimulationManager)
#-----------------------------------------------------------------------------
# Add shaders
#-----------------------------------------------------------------------------
include(imstkCopyAndCompileShaders)
CopyAndCompileShaders()
#-----------------------------------------------------------------------------
# Associate external data
#-----------------------------------------------------------------------------
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
// Generate a fluid simulation example in with a bunny-shape fluid dropping onto a box
#define SCENE_ID 4
#include "../SPHFluidExample.hpp"
......@@ -68,7 +68,8 @@ main(int argc, char* argv[])
}
// Override particle radius for scene3 because particles in this scene were pre-generated using particle radius 0.08
if (SCENE_ID == 3)
if (SCENE_ID == 3
|| SCENE_ID == 4)
{
particleRadius = 0.08;
}
......@@ -87,37 +88,44 @@ main(int argc, char* argv[])
statusManager->setStatusFontColor(VTKTextStatusManager::Custom, Color::Red);
// Generate fluid and solid objects
auto fluidObj = generateFluid(scene, particleRadius);
auto solids = generateSolids(scene);
auto fluids = generateFluid(scene, particleRadius);
auto solids = generateSolids(scene);
sdk->getSceneManager(scene)->setPostUpdateCallback([&](Module*) {
statusManager->setCustomStatus("Number of particles: " +
std::to_string(fluidObj->getSPHModel()->getState().getNumParticles()) +
size_t numParticles = 0;
for (const auto& fluid: fluids)
{
numParticles += fluid->getSPHModel()->getState().getNumParticles();
}
statusManager->setCustomStatus("Number of particles: " + std::to_string(numParticles) +
"\nNumber of solids: " + std::to_string(solids.size()));
});
// Collision between fluid and solid objects
auto colGraph = scene->getCollisionGraph();
for (auto& solid: solids)
for (const auto& solid: solids)
{
if (std::dynamic_pointer_cast<Plane>(solid->getCollidingGeometry()))
for (const auto& fluid: fluids)
{
colGraph->addInteractionPair(fluidObj, solid,
if (std::dynamic_pointer_cast<Plane>(solid->getCollidingGeometry()))
{
colGraph->addInteractionPair(fluid, solid,
CollisionDetection::Type::PointSetToPlane,
CollisionHandling::Type::SPH,
CollisionHandling::Type::None);
}
else if (std::dynamic_pointer_cast<Sphere>(solid->getCollidingGeometry()))
{
colGraph->addInteractionPair(fluidObj, solid,
}
else if (std::dynamic_pointer_cast<Sphere>(solid->getCollidingGeometry()))
{
colGraph->addInteractionPair(fluid, solid,
CollisionDetection::Type::PointSetToSphere,
CollisionHandling::Type::SPH,
CollisionHandling::Type::None);
}
else
{
LOG(FATAL) << "Invalid collision object";
}
else
{
LOG(FATAL) << "Invalid collision object";
}
}
}
......
......@@ -28,7 +28,8 @@ using namespace imstk;
///
/// \brief Generate two planes and a solid sphere
///
std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene1(const std::shared_ptr<Scene>& scene)
std::vector<std::shared_ptr<CollidingObject>>
generateSolidsScene1(const std::shared_ptr<Scene>& scene)
{
std::vector<std::shared_ptr<CollidingObject>> solids;
......@@ -39,7 +40,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene1(const std::sh
geometry->setNormal(Vec3d(0, 1, -0.5));
auto visualModel = std::make_shared<VisualModel>(geometry);
auto material = std::make_shared<RenderMaterial>();
auto material = std::make_shared<RenderMaterial>();
material->setColor(Color::DarkGray);
visualModel->setRenderMaterial(material);
......@@ -56,7 +57,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene1(const std::sh
geometry->setNormal(Vec3d(0, 1, 1));
auto visualModel = std::make_shared<VisualModel>(geometry);
auto material = std::make_shared<RenderMaterial>();
auto material = std::make_shared<RenderMaterial>();
material->setColor(Color::LightGray);
visualModel->setRenderMaterial(material);
......@@ -89,7 +90,8 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene1(const std::sh
///
/// \brief Generate two planes
///
std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene2(const std::shared_ptr<Scene>& scene)
std::vector<std::shared_ptr<CollidingObject>>
generateSolidsScene2(const std::shared_ptr<Scene>& scene)
{
std::vector<std::shared_ptr<CollidingObject>> solids;
......@@ -100,7 +102,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene2(const std::sh
geometry->setNormal(Vec3d(0, 1, -0.5));
auto visualModel = std::make_shared<VisualModel>(geometry);
auto material = std::make_shared<RenderMaterial>();
auto material = std::make_shared<RenderMaterial>();
material->setColor(Color::DarkGray);
visualModel->setRenderMaterial(material);
......@@ -117,7 +119,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene2(const std::sh
geometry->setNormal(Vec3d(0, 1, 1));
auto visualModel = std::make_shared<VisualModel>(geometry);
auto material = std::make_shared<RenderMaterial>();
auto material = std::make_shared<RenderMaterial>();
material->setColor(Color::LightGray);
visualModel->setRenderMaterial(material);
......@@ -134,7 +136,8 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene2(const std::sh
///
/// \brief Generate an open box by 5 planes: 1 floor and 4 walls
///
std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene3(const std::shared_ptr<Scene>& scene)
std::vector<std::shared_ptr<CollidingObject>>
generateSolidsScene3(const std::shared_ptr<Scene>& scene)
{
std::vector<std::shared_ptr<CollidingObject>> solids;
......@@ -142,10 +145,17 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene3(const std::sh
auto geometry = std::make_shared<Plane>();
geometry->setWidth(14);
geometry->setPosition(0, -6, 0);
geometry->setNormal(Vec3d(0, 1, 0));
if (SCENE_ID == 4) // multiple fluid
{
geometry->setNormal(Vec3d(0.3, 1, 0));
}
else
{
geometry->setNormal(Vec3d(0, 1, 0));
}
auto visualModel = std::make_shared<VisualModel>(geometry);
auto material = std::make_shared<RenderMaterial>();
auto material = std::make_shared<RenderMaterial>();
material->setColor(Color(0.2, 0.2, 0.2, 1.0));
visualModel->setRenderMaterial(material);
......@@ -162,7 +172,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene3(const std::sh
geometry->setNormal(Vec3d(0, 0, 1));
auto visualModel = std::make_shared<VisualModel>(geometry);
auto material = std::make_shared<RenderMaterial>();
auto material = std::make_shared<RenderMaterial>();
material->setColor(Color::LightGray);
visualModel->setRenderMaterial(material);
......@@ -179,7 +189,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene3(const std::sh
geometry->setNormal(Vec3d(0, 0, -1));
auto visualModel = std::make_shared<VisualModel>(geometry);
auto material = std::make_shared<RenderMaterial>();
auto material = std::make_shared<RenderMaterial>();
material->setColor(Color::LightGray);
visualModel->setRenderMaterial(material);
......@@ -196,7 +206,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene3(const std::sh
geometry->setNormal(Vec3d(-1, 0, 0));
auto visualModel = std::make_shared<VisualModel>(geometry);
auto material = std::make_shared<RenderMaterial>();
auto material = std::make_shared<RenderMaterial>();
material->setColor(Color::LightGray);
visualModel->setRenderMaterial(material);
......@@ -213,7 +223,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene3(const std::sh
geometry->setNormal(Vec3d(1, 0, 0));
auto visualModel = std::make_shared<VisualModel>(geometry);
auto material = std::make_shared<RenderMaterial>();
auto material = std::make_shared<RenderMaterial>();
material->setColor(Color::LightGray);
visualModel->setRenderMaterial(material);
......@@ -227,7 +237,8 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene3(const std::sh
return solids;
}
std::vector<std::shared_ptr<CollidingObject>> generateSolids(const std::shared_ptr<Scene>& scene)
std::vector<std::shared_ptr<CollidingObject>>
generateSolids(const std::shared_ptr<Scene>& scene)
{
switch (SCENE_ID)
{
......@@ -236,6 +247,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolids(const std::shared_p
case 2:
return generateSolidsScene2(scene);
case 3:
case 4:
return generateSolidsScene3(scene);
default:
LOG(FATAL) << "Invalid scene index";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment