From 4c063bed4dbb376e79f59b17391bb2b66e1207b7 Mon Sep 17 00:00:00 2001 From: Jan Bender Date: Fri, 12 Jan 2024 08:20:24 +0100 Subject: [PATCH] - fixed z-sort - added parameter stepsPerZSort - bugfix in the PBDWrapper - the wrapper ignored some settings of the scene file --- Changelog.txt | 5 + README.md | 98 +------------------ SPlisHSPlasH/DFSPH/TimeStepDFSPH.cpp | 18 +--- SPlisHSPlasH/DFSPH/TimeStepDFSPH.h | 5 +- SPlisHSPlasH/ICSPH/TimeStepICSPH.cpp | 18 +--- SPlisHSPlasH/ICSPH/TimeStepICSPH.h | 5 +- SPlisHSPlasH/IISPH/TimeStepIISPH.cpp | 18 +--- SPlisHSPlasH/IISPH/TimeStepIISPH.h | 5 +- SPlisHSPlasH/PBF/TimeStepPBF.cpp | 18 +--- SPlisHSPlasH/PBF/TimeStepPBF.h | 5 +- SPlisHSPlasH/PCISPH/TimeStepPCISPH.cpp | 18 +--- SPlisHSPlasH/PCISPH/TimeStepPCISPH.h | 5 +- SPlisHSPlasH/PF/TimeStepPF.cpp | 18 +--- SPlisHSPlasH/PF/TimeStepPF.h | 5 +- SPlisHSPlasH/Simulation.cpp | 18 ++++ SPlisHSPlasH/Simulation.h | 5 + SPlisHSPlasH/TimeStep.h | 5 + SPlisHSPlasH/WCSPH/TimeStepWCSPH.cpp | 18 +--- SPlisHSPlasH/WCSPH/TimeStepWCSPH.h | 5 +- .../PBDWrapper.cpp | 23 +++-- .../PositionBasedDynamicsWrapper/PBDWrapper.h | 1 - Tests/ReadWriteState/ReadWriteStateTests.cpp | 3 + version.txt | 2 +- 23 files changed, 82 insertions(+), 239 deletions(-) diff --git a/Changelog.txt b/Changelog.txt index 0e84d86f..6837b418 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,3 +1,8 @@ +2.13.1 + - fixed z-sort + - added parameter stepsPerZSort + - bugfix in the PBDWrapper - the wrapper ignored some settings of the scene file + 2.13.0 - added implementation of surface tension method: Jeske et al. "Implicit Surface Tension for SPH Fluid Simulation", ACM Transactions on Graphics, 2023 (thanks to Stefan Rhys Jeske) diff --git a/README.md b/README.md index c5011bd9..0ad12133 100644 --- a/README.md +++ b/README.md @@ -96,105 +96,15 @@ SPlisHSPlasH implements: * a Maya plugin to model and generate scene files * a ParaView plugin to import particle data -## Pressure Solvers +A list of all implemented simulation methods can be found here: +[https://splishsplash.physics-simulation.org/features](https://splishsplash.physics-simulation.org/features/) -The SPlisHSPlasH library implements the following pressure solvers: -* Weakly compressible SPH for free surface flows (WCSPH) -* Predictive-corrective incompressible SPH (PCISPH) -* Position based fluids (PBF) -* Implicit incompressible SPH (IISPH) -* Divergence-free smoothed particle hydrodynamics (DFSPH) -* Projective Fluids (PF) -* Implicit compressible SPH (ICSPH) +## Screenshots & Videos -## Boundary Handling +[https://splishsplash.physics-simulation.org/gallery](https://splishsplash.physics-simulation.org/gallery/) -The SPlisHSPlasH library implements the following boundary handling methods: -* Nadir Akinci, Markus Ihmsen, Gizem Akinci, Barbara Solenthaler, and Matthias Teschner, "Versatile rigid-fluid coupling for incompressible SPH", ACM Transactions on Graphics 31(4), 2012 -* Dan Koschier and Jan Bender, "Density Maps for Improved SPH Boundary Handling", In Proceedings of ACM SIGGRAPH / EUROGRAPHICS Symposium on Computer Animation (SCA), 2017 -* Jan Bender, Tassilo Kugelstadt, Marcel Weiler, Dan Koschier, "Volume Maps: An Implicit Boundary Representation for SPH", ACM SIGGRAPH Conference on Motion, Interaction and Games, 2019 - -## Viscosity - -The SPlisHSPlasH library implements explicit viscosity methods: - -* Standard SPH formulation of viscosity - -and the implicit methods of the following publications: - -* Jan Bender and Dan Koschier, "Divergence-free SPH for incompressible and viscous fluids", IEEE Transactions on Visualization and Computer Graphics, 2017 -* Andreas Peer, Markus Ihmsen, Jens Cornelis, and Matthias Teschner, "An Implicit Viscosity Formulation for SPH Fluids", ACM Transactions on Graphics, 34(4), 2015 -* Andreas Peer and Matthias Teschner. Prescribed Velocity Gradients for Highly Viscous SPH Fluids with Vorticity Diffusion. IEEE Transactions on Visualization and Computer Graphics, 2016 -* An improved version of: Tetsuya Takahashi, Yoshinori Dobashi, Issei Fujishiro, Tomoyuki Nishita, and Ming C. Lin. Implicit Formulation for SPH-based Viscous Fluids. Computer Graphics Forum, 34, 2015. -* Marcel Weiler, Dan Koschier, Magnus Brand and Jan Bender. A Physically Consistent Implicit Viscosity Solver for SPH Fluids. Computer Graphics Forum (Eurographics), 37(2), 2018 - -## Surface Tension - -The SPlisHSPlasH library implements the surface tension methods of the following publications: - -* Markus Becker and Matthias Teschner. Weakly compressible SPH for free surface flows. In Proceedings of ACM SIGGRAPH/Eurographics Symposium on Computer Animation, 2007. Eurographics Association. -* Nadir Akinci, Gizem Akinci, and Matthias Teschner. Versatile surface tension and adhesion for SPH fluids. ACM Trans. Graph., 32(6):182:1–182:8, 2013. -* Xiaowei He, Huamin Wang, Fengjun Zhang, Hongan Wang, Guoping Wang, and Kun Zhou, "Robust simulation of sparsely sampled thin features in SPH-based free surface flows", ACM Transactions on Graphics, 34(1), 2014. -* F. Zorilla, M. Ritter, J. Sappl, W. Rauch, M. Harders, "Accelerating Surface Tension Calculation in SPH via Particle Classification and Monte Carlo Integration", Computers 9, 23, 2020. - -## Vorticity - -The SPlisHSPlasH library implements the vorticity methods of the following publications: - -* Jan Bender, Dan Koschier, Tassilo Kugelstadt and Marcel Weiler. A Micropolar Material Model for Turbulent SPH Fluids. In Proceedings of ACM SIGGRAPH / EUROGRAPHICS Symposium on Computer Animation, 2017 -* Miles Macklin and Matthias Müller. Position based fluids. ACM Trans. Graph., 32(4):104:1–104:12, July 2013. - -## Drag Forces - -The SPlisHSPlasH library implements the drag force computation of the following publications: - -* Christoph Gissler, Stefan Band, Andreas Peer, Markus Ihmsen and Matthias Teschner. Approximate Air-Fluid Interactions for SPH. In Proceedings of Virtual Reality Interactions and Physical Simulations, 2017 -* Miles Macklin, Matthias Müller, Nuttapong Chentanez and Tae-Yong Kim. Unified Particle Physics for Real-Time Applications. ACM Trans. Graph., 33(4), 2014 - -## Elastic Forces - -* M. Becker, M. Ihmsen, and M. Teschner. Corotated SPH for deformable solids. Proceedings of Eurographics Conference on Natural Phenomena, 2009 -* A. Peer, C. Gissler, S. Band, and M. Teschner. An Implicit SPH Formulation for Incompressible Linearly Elastic Solids. Computer Graphics Forum, 2017 -* Tassilo Kugelstadt, Jan Bender, José Antonio Fernández-Fernández, Stefan Rhys Jeske, Fabian Löschner, and Andreas Longva. Fast Corotated Elastic SPH Solids with Implicit Zero-Energy Mode Control. Proceedings of the ACM on Computer Graphics and Interactive Techniques, 2021 - - -## Multi-Phase Fluid Simulation - -The SPlisHSPlasH library implements the following publication to realize multi-phase simulations: - -* B. Solenthaler and R. Pajarola. Density Contrast SPH Interfaces. In Proceedings of ACM SIGGRAPH/Eurographics Symposium on Computer Animation, 2008. - -## Volume Sampling - -The SPlisHSPlasH library implements the volume sampling techniques of following publications: - - * M. Jiang, Y. Zhou, R. Wang, R. Southern, J. J. Zhang. Blue noise sampling using an SPH-based method. ACM Transactions on Graphics, 2015 - * Tassilo Kugelstadt, Jan Bender, José Antonio Fernández-Fernández, Stefan Rhys Jeske, Fabian Löschner, and Andreas Longva. Fast Corotated Elastic SPH Solids with Implicit Zero-Energy Mode Control. Proceedings of the ACM on Computer Graphics and Interactive Techniques, 2021 - - -## Screenshots - -|![](https://raw.githubusercontent.com/InteractiveComputerGraphics/SPlisHSPlasH/master/doc/images/SPlisHSPlasH2.jpg)|![](https://raw.githubusercontent.com/InteractiveComputerGraphics/SPlisHSPlasH/master/doc/images/SPlisHSPlasH1.jpg)| -|--|--| -|![](https://raw.githubusercontent.com/InteractiveComputerGraphics/SPlisHSPlasH/master/doc/images/SPlisHSPlasH3.jpg)|![](https://raw.githubusercontent.com/InteractiveComputerGraphics/SPlisHSPlasH/master/doc/images/SPlisHSPlasH4.jpg)| - -## Videos - -The following videos were generated using the SPlisHSPlasH library: - -*A Micropolar Material Model for Turbulent SPH Fluids* | *Density Maps for Improved SPH Boundary Handling* -:---:|:---: -[![Video](https://img.youtube.com/vi/fsvDbzEui3w/0.jpg)](https://www.youtube.com/watch?v=fsvDbzEui3w) | [![Video](https://img.youtube.com/vi/P82qmTAahg0/0.jpg)](https://www.youtube.com/watch?v=P82qmTAahg0) -*Divergence-Free Smoothed Particle Hydrodynamics* | *Divergence-Free SPH for Incompressible and Viscous Fluids* -[![Video](https://img.youtube.com/vi/POnmzzhc5E0/0.jpg)](https://www.youtube.com/watch?v=POnmzzhc5E0) | [![Video](https://img.youtube.com/vi/tl4mx0TtaAc/0.jpg)](https://www.youtube.com/watch?v=tl4mx0TtaAc) -*A Physically Consistent Implicit Viscosity Solver for SPH Fluids* | *Turbulent Micropolar SPH Fluids with Foam* -[![Video](https://img.youtube.com/vi/D_nEhix1G-w/0.jpg)](https://www.youtube.com/watch?v=D_nEhix1G-w) | [![Video](https://img.youtube.com/vi/elZieJNBYqk/0.jpg)](https://www.youtube.com/watch?v=elZieJNBYqk) -*Volume Maps: An Implicit Boundary Representation for SPH* | *Implicit Frictional Boundary Handling for SPH* -[![Video](https://img.youtube.com/vi/AV_pl1bMIb8/0.jpg)](https://www.youtube.com/watch?v=AV_pl1bMIb8) | [![Video](https://img.youtube.com/vi/1u5N0eedzic/0.jpg)](https://www.youtube.com/watch?v=1u5N0eedzic) -*Fast Corotated Elastic SPH Solids with Implicit Zero-Energy Mode Control* | *A comparison of linear consistent correction methods for first-order SPH derivatives* -[![Video](https://img.youtube.com/vi/8NkyiftmDN0/0.jpg)](https://www.youtube.com/watch?v=8NkyiftmDN0) | [![Video](https://img.youtube.com/vi/k0kKR8mXmK4/0.jpg)](https://www.youtube.com/watch?v=k0kKR8mXmK4) ## Citation diff --git a/SPlisHSPlasH/DFSPH/TimeStepDFSPH.cpp b/SPlisHSPlasH/DFSPH/TimeStepDFSPH.cpp index b9217d43..31668161 100644 --- a/SPlisHSPlasH/DFSPH/TimeStepDFSPH.cpp +++ b/SPlisHSPlasH/DFSPH/TimeStepDFSPH.cpp @@ -27,7 +27,6 @@ TimeStepDFSPH::TimeStepDFSPH() : m_simulationData() { m_simulationData.init(); - m_counter = 0; m_iterationsV = 0; m_enableDivergenceSolver = true; m_maxIterationsV = 100; @@ -97,7 +96,7 @@ void TimeStepDFSPH::step() ////////////////////////////////////////////////////////////////////////// // search the neighbors for all particles ////////////////////////////////////////////////////////////////////////// - performNeighborhoodSearch(); + sim->performNeighborhoodSearch(); #ifdef USE_PERFORMANCE_OPTIMIZATION ////////////////////////////////////////////////////////////////////////// @@ -684,24 +683,13 @@ void TimeStepDFSPH::reset() { TimeStep::reset(); m_simulationData.reset(); - m_counter = 0; m_iterations = 0; m_iterationsV = 0; } -void TimeStepDFSPH::performNeighborhoodSearch() +void TimeStepDFSPH::performNeighborhoodSearchSort() { - if (Simulation::getCurrent()->zSortEnabled()) - { - if (m_counter % 500 == 0) - { - Simulation::getCurrent()->performNeighborhoodSearchSort(); - m_simulationData.performNeighborhoodSearchSort(); - } - m_counter++; - } - - Simulation::getCurrent()->performNeighborhoodSearch(); + m_simulationData.performNeighborhoodSearchSort(); } void TimeStepDFSPH::emittedParticles(FluidModel *model, const unsigned int startIndex) diff --git a/SPlisHSPlasH/DFSPH/TimeStepDFSPH.h b/SPlisHSPlasH/DFSPH/TimeStepDFSPH.h index 07478a0e..4b39af93 100644 --- a/SPlisHSPlasH/DFSPH/TimeStepDFSPH.h +++ b/SPlisHSPlasH/DFSPH/TimeStepDFSPH.h @@ -25,7 +25,6 @@ namespace SPH { protected: SimulationDataDFSPH m_simulationData; - unsigned int m_counter; const Real m_eps = static_cast(1.0e-5); bool m_enableDivergenceSolver; unsigned int m_iterationsV; @@ -43,9 +42,7 @@ namespace SPH void computePressureAccel(const unsigned int fluidModelIndex, const unsigned int i, const Real density0, std::vector>& pressure_rho2, const bool applyBoundaryForces = false); Real compute_aij_pj(const unsigned int fluidModelIndex, const unsigned int i); - /** Perform the neighborhood search for all fluid particles. - */ - void performNeighborhoodSearch(); + virtual void performNeighborhoodSearchSort(); virtual void emittedParticles(FluidModel *model, const unsigned int startIndex); /** Init all generic parameters */ diff --git a/SPlisHSPlasH/ICSPH/TimeStepICSPH.cpp b/SPlisHSPlasH/ICSPH/TimeStepICSPH.cpp index de8ac3ff..b2c036bd 100644 --- a/SPlisHSPlasH/ICSPH/TimeStepICSPH.cpp +++ b/SPlisHSPlasH/ICSPH/TimeStepICSPH.cpp @@ -22,7 +22,6 @@ TimeStepICSPH::TimeStepICSPH() : TimeStep() { m_simulationData.init(); - m_counter = 0; m_lambda = 200000; m_clamping = true; @@ -78,7 +77,7 @@ void TimeStepICSPH::step() ////////////////////////////////////////////////////////////////////////// // search the neighbors for all particles ////////////////////////////////////////////////////////////////////////// - performNeighborhoodSearch(); + sim->performNeighborhoodSearch(); #ifdef USE_PERFORMANCE_OPTIMIZATION ////////////////////////////////////////////////////////////////////////// @@ -159,7 +158,6 @@ void TimeStepICSPH::reset() { TimeStep::reset(); m_simulationData.reset(); - m_counter = 0; } @@ -580,19 +578,9 @@ void TimeStepICSPH::computePressureAccels(const unsigned int fluidModelIndex) } } -void TimeStepICSPH::performNeighborhoodSearch() +void TimeStepICSPH::performNeighborhoodSearchSort() { - if (Simulation::getCurrent()->zSortEnabled()) - { - if (m_counter % 500 == 0) - { - Simulation::getCurrent()->performNeighborhoodSearchSort(); - m_simulationData.performNeighborhoodSearchSort(); - } - m_counter++; - } - - Simulation::getCurrent()->performNeighborhoodSearch(); + m_simulationData.performNeighborhoodSearchSort(); } void TimeStepICSPH::emittedParticles(FluidModel *model, const unsigned int startIndex) diff --git a/SPlisHSPlasH/ICSPH/TimeStepICSPH.h b/SPlisHSPlasH/ICSPH/TimeStepICSPH.h index 444b125f..f0cab0e3 100644 --- a/SPlisHSPlasH/ICSPH/TimeStepICSPH.h +++ b/SPlisHSPlasH/ICSPH/TimeStepICSPH.h @@ -23,7 +23,6 @@ namespace SPH Real m_lambda; bool m_clamping; const Real m_psi = 1.5; - unsigned int m_counter; void computeDensityAdv(const unsigned int fluidModelIndex); void compute_aii(const unsigned int fluidModelIndex); @@ -34,9 +33,7 @@ namespace SPH /** Determine the pressure accelerations when the pressure is already known. */ void computePressureAccels(const unsigned int fluidModelIndex); - /** Perform the neighborhood search for all fluid particles. - */ - void performNeighborhoodSearch(); + virtual void performNeighborhoodSearchSort(); virtual void initParameters(); virtual void emittedParticles(FluidModel *model, const unsigned int startIndex); diff --git a/SPlisHSPlasH/IISPH/TimeStepIISPH.cpp b/SPlisHSPlasH/IISPH/TimeStepIISPH.cpp index 55bf8d2c..4f2aba52 100644 --- a/SPlisHSPlasH/IISPH/TimeStepIISPH.cpp +++ b/SPlisHSPlasH/IISPH/TimeStepIISPH.cpp @@ -18,7 +18,6 @@ TimeStepIISPH::TimeStepIISPH() : TimeStep() { m_simulationData.init(); - m_counter = 0; Simulation *sim = Simulation::getCurrent(); const unsigned int nModels = sim->numberOfFluidModels(); @@ -62,7 +61,7 @@ void TimeStepIISPH::step() for (unsigned int fluidModelIndex = 0; fluidModelIndex < nModels; fluidModelIndex++) clearAccelerations(fluidModelIndex); - performNeighborhoodSearch(); + sim->performNeighborhoodSearch(); #ifdef USE_PERFORMANCE_OPTIMIZATION precomputeValues(); @@ -105,7 +104,6 @@ void TimeStepIISPH::reset() { TimeStep::reset(); m_simulationData.reset(); - m_counter = 0; } void TimeStepIISPH::predictAdvection(const unsigned int fluidModelIndex) @@ -520,19 +518,9 @@ void TimeStepIISPH::computePressureAccels(const unsigned int fluidModelIndex) } } -void TimeStepIISPH::performNeighborhoodSearch() +void TimeStepIISPH::performNeighborhoodSearchSort() { - if (Simulation::getCurrent()->zSortEnabled()) - { - if (m_counter % 500 == 0) - { - Simulation::getCurrent()->performNeighborhoodSearchSort(); - m_simulationData.performNeighborhoodSearchSort(); - } - m_counter++; - } - - Simulation::getCurrent()->performNeighborhoodSearch(); + m_simulationData.performNeighborhoodSearchSort(); } void TimeStepIISPH::emittedParticles(FluidModel *model, const unsigned int startIndex) diff --git a/SPlisHSPlasH/IISPH/TimeStepIISPH.h b/SPlisHSPlasH/IISPH/TimeStepIISPH.h index 77b40292..b3b1cc41 100644 --- a/SPlisHSPlasH/IISPH/TimeStepIISPH.h +++ b/SPlisHSPlasH/IISPH/TimeStepIISPH.h @@ -20,7 +20,6 @@ namespace SPH { protected: SimulationDataIISPH m_simulationData; - unsigned int m_counter; void predictAdvection(const unsigned int fluidModelIndex); void pressureSolve(); @@ -30,9 +29,7 @@ namespace SPH /** Determine the pressure accelerations when the pressure is already known. */ void computePressureAccels(const unsigned int fluidModelIndex); - /** Perform the neighborhood search for all fluid particles. - */ - void performNeighborhoodSearch(); + virtual void performNeighborhoodSearchSort(); virtual void emittedParticles(FluidModel *model, const unsigned int startIndex); diff --git a/SPlisHSPlasH/PBF/TimeStepPBF.cpp b/SPlisHSPlasH/PBF/TimeStepPBF.cpp index eafb0553..88bafcbf 100644 --- a/SPlisHSPlasH/PBF/TimeStepPBF.cpp +++ b/SPlisHSPlasH/PBF/TimeStepPBF.cpp @@ -24,7 +24,6 @@ TimeStepPBF::TimeStepPBF() : TimeStep() { m_simulationData.init(); - m_counter = 0; m_velocityUpdateMethod = 0; Simulation *sim = Simulation::getCurrent(); @@ -88,7 +87,7 @@ void TimeStepPBF::step() } // Perform neighborhood search - performNeighborhoodSearch(); + sim->performNeighborhoodSearch(); #ifdef USE_PERFORMANCE_OPTIMIZATION precomputeValues(); @@ -163,7 +162,6 @@ void TimeStepPBF::reset() { TimeStep::reset(); m_simulationData.reset(); - m_counter = 0; } @@ -383,19 +381,9 @@ void TimeStepPBF::pressureSolveIteration(const unsigned int fluidModelIndex, Rea } } -void TimeStepPBF::performNeighborhoodSearch() +void TimeStepPBF::performNeighborhoodSearchSort() { - if (Simulation::getCurrent()->zSortEnabled()) - { - if (m_counter % 500 == 0) - { - Simulation::getCurrent()->performNeighborhoodSearchSort(); - m_simulationData.performNeighborhoodSearchSort(); - } - m_counter++; - } - - Simulation::getCurrent()->performNeighborhoodSearch(); + m_simulationData.performNeighborhoodSearchSort(); } void TimeStepPBF::emittedParticles(FluidModel *model, const unsigned int startIndex) diff --git a/SPlisHSPlasH/PBF/TimeStepPBF.h b/SPlisHSPlasH/PBF/TimeStepPBF.h index 5c2c8e56..98d8b46d 100644 --- a/SPlisHSPlasH/PBF/TimeStepPBF.h +++ b/SPlisHSPlasH/PBF/TimeStepPBF.h @@ -23,7 +23,6 @@ namespace SPH { protected: SimulationDataPBF m_simulationData; - unsigned int m_counter; int m_velocityUpdateMethod; /** Perform a position-based correction step for the following density constraint:\n @@ -32,9 +31,7 @@ namespace SPH void pressureSolve(); void pressureSolveIteration(const unsigned int fluidModelIndex, Real &avg_density_err); - /** Perform the neighborhood search for all fluid particles. - */ - void performNeighborhoodSearch(); + virtual void performNeighborhoodSearchSort(); virtual void emittedParticles(FluidModel *model, const unsigned int startIndex); diff --git a/SPlisHSPlasH/PCISPH/TimeStepPCISPH.cpp b/SPlisHSPlasH/PCISPH/TimeStepPCISPH.cpp index 2d64ffa2..d5f77b3d 100644 --- a/SPlisHSPlasH/PCISPH/TimeStepPCISPH.cpp +++ b/SPlisHSPlasH/PCISPH/TimeStepPCISPH.cpp @@ -17,7 +17,6 @@ TimeStepPCISPH::TimeStepPCISPH() : TimeStep() { m_simulationData.init(); - m_counter = 0; m_minIterations = 3; Simulation *sim = Simulation::getCurrent(); @@ -54,7 +53,7 @@ void TimeStepPCISPH::step() for (unsigned int fluidModelIndex = 0; fluidModelIndex < nModels; fluidModelIndex++) clearAccelerations(fluidModelIndex); - performNeighborhoodSearch(); + sim->performNeighborhoodSearch(); #ifdef USE_PERFORMANCE_OPTIMIZATION precomputeValues(); @@ -301,22 +300,11 @@ void TimeStepPCISPH::reset() { TimeStep::reset(); m_simulationData.reset(); - m_counter = 0; } -void TimeStepPCISPH::performNeighborhoodSearch() +void TimeStepPCISPH::performNeighborhoodSearchSort() { - if (Simulation::getCurrent()->zSortEnabled()) - { - if (m_counter % 500 == 0) - { - Simulation::getCurrent()->performNeighborhoodSearchSort(); - m_simulationData.performNeighborhoodSearchSort(); - } - m_counter++; - } - - Simulation::getCurrent()->performNeighborhoodSearch(); + m_simulationData.performNeighborhoodSearchSort(); } void TimeStepPCISPH::emittedParticles(FluidModel *model, const unsigned int startIndex) diff --git a/SPlisHSPlasH/PCISPH/TimeStepPCISPH.h b/SPlisHSPlasH/PCISPH/TimeStepPCISPH.h index e8b401af..d6b83ca4 100644 --- a/SPlisHSPlasH/PCISPH/TimeStepPCISPH.h +++ b/SPlisHSPlasH/PCISPH/TimeStepPCISPH.h @@ -19,14 +19,11 @@ namespace SPH { protected: SimulationDataPCISPH m_simulationData; - unsigned int m_counter; void pressureSolve(); void pressureSolveIteration(const unsigned int fluidModelIndex, Real &avg_density_err); - /** Perform the neighborhood search for all fluid particles. - */ - void performNeighborhoodSearch(); + virtual void performNeighborhoodSearchSort(); virtual void emittedParticles(FluidModel *model, const unsigned int startIndex); diff --git a/SPlisHSPlasH/PF/TimeStepPF.cpp b/SPlisHSPlasH/PF/TimeStepPF.cpp index 8da51224..a56aeaef 100644 --- a/SPlisHSPlasH/PF/TimeStepPF.cpp +++ b/SPlisHSPlasH/PF/TimeStepPF.cpp @@ -51,7 +51,6 @@ using AtomicRealVec = std::vector < atomic_wrapper >; TimeStepPF::TimeStepPF() : TimeStep(), m_stiffness(50000.0), - m_counter(0), m_numActiveParticlesTotal(0) { m_simulationData.init(); @@ -103,7 +102,7 @@ void TimeStepPF::step() clearAccelerations(fluidModelIndex); initialGuessForPositions(fluidModelIndex); } - performNeighborhoodSearch(); + sim->performNeighborhoodSearch(); #ifdef USE_PERFORMANCE_OPTIMIZATION precomputeValues(); @@ -140,7 +139,6 @@ void TimeStepPF::reset() { TimeStep::reset(); m_simulationData.reset(); - m_counter = 0; } void TimeStepPF::initialGuessForPositions(const unsigned int fluidModelIndex) @@ -598,19 +596,9 @@ void SPH::TimeStepPF::matrixVecProd(const Real* vec, Real *result, void *userDat } } -void TimeStepPF::performNeighborhoodSearch() +void TimeStepPF::performNeighborhoodSearchSort() { - if (Simulation::getCurrent()->zSortEnabled()) - { - if (m_counter % 500 == 0) - { - Simulation::getCurrent()->performNeighborhoodSearchSort(); - m_simulationData.performNeighborhoodSearchSort(); - } - m_counter++; - } - - Simulation::getCurrent()->performNeighborhoodSearch(); + m_simulationData.performNeighborhoodSearchSort(); } void TimeStepPF::emittedParticles(FluidModel *model, const unsigned int startIndex) diff --git a/SPlisHSPlasH/PF/TimeStepPF.h b/SPlisHSPlasH/PF/TimeStepPF.h index 27440888..eb71cd4a 100644 --- a/SPlisHSPlasH/PF/TimeStepPF.h +++ b/SPlisHSPlasH/PF/TimeStepPF.h @@ -35,7 +35,6 @@ namespace SPH SimulationDataPF m_simulationData; Solver m_solver; Real m_stiffness; - unsigned int m_counter; unsigned int m_numActiveParticlesTotal; void initialGuessForPositions(const unsigned int fluidModelIndex); @@ -45,9 +44,7 @@ namespace SPH void matrixFreeRHS(const VectorXr & x, VectorXr & result); - /** Perform the neighborhood search for all fluid particles. - */ - void performNeighborhoodSearch(); + virtual void performNeighborhoodSearchSort(); virtual void emittedParticles(FluidModel *model, const unsigned int startIndex) override; virtual void initParameters() override; diff --git a/SPlisHSPlasH/Simulation.cpp b/SPlisHSPlasH/Simulation.cpp index 79797b87..7f518880 100644 --- a/SPlisHSPlasH/Simulation.cpp +++ b/SPlisHSPlasH/Simulation.cpp @@ -28,6 +28,7 @@ int Simulation::CFL_FACTOR = -1; int Simulation::CFL_MIN_TIMESTEPSIZE = -1; int Simulation::CFL_MAX_TIMESTEPSIZE = -1; int Simulation::ENABLE_Z_SORT = -1; +int Simulation::STEPS_PER_Z_SORT = -1; int Simulation::KERNEL_METHOD = -1; int Simulation::GRAD_KERNEL_METHOD = -1; int Simulation::ENUM_KERNEL_CUBIC = -1; @@ -80,6 +81,8 @@ Simulation::Simulation () m_simulationIsInitialized = false; m_sim2D = false; m_enableZSort = true; + m_stepsPerZSort = 500; + m_counter = 0; m_animationFieldSystem = new AnimationFieldSystem(); m_boundaryHandlingMethod = static_cast(BoundaryHandlingMethods::Bender2019); @@ -170,6 +173,11 @@ void Simulation::initParameters() setGroup(ENABLE_Z_SORT, "Simulation|Simulation"); setDescription(ENABLE_Z_SORT, "Enable z-sort to improve cache hits."); + STEPS_PER_Z_SORT = createNumericParameter("enableZSort", "Simulation steps per z-sort", &m_stepsPerZSort); + setGroup(STEPS_PER_Z_SORT, "Simulation|Simulation"); + setDescription(STEPS_PER_Z_SORT, "Number of simulation steps which are performed before a z-sort is applied."); + static_cast(getParameter(STEPS_PER_Z_SORT))->setMinValue(1u); + ParameterBase::GetFunc getRadiusFct = std::bind(&Simulation::getParticleRadius, this); ParameterBase::SetFunc setRadiusFct = std::bind(&Simulation::setParticleRadius, this, std::placeholders::_1); PARTICLE_RADIUS = createNumericParameter("particleRadius", "Particle radius", getRadiusFct, setRadiusFct); @@ -516,6 +524,7 @@ void Simulation::reset() m_animationFieldSystem->reset(); + m_counter = 0; performNeighborhoodSearchSort(); TimeManager::getCurrent()->setTime(0.0); @@ -594,6 +603,14 @@ void Simulation::setSimulationMethod(const int val) void Simulation::performNeighborhoodSearch() { + if (zSortEnabled()) + { + if (m_counter % m_stepsPerZSort == 0) + { + performNeighborhoodSearchSort(); + } + m_counter++; + } START_TIMING("neighborhood_search"); m_neighborhoodSearch->find_neighbors(); STOP_TIMING_AVG; @@ -616,6 +633,7 @@ void Simulation::performNeighborhoodSearchSort() BoundaryModel *bm = getBoundaryModel(i); bm->performNeighborhoodSearchSort(); } + getTimeStep()->performNeighborhoodSearchSort(); #ifdef USE_DEBUG_TOOLS m_debugTools->performNeighborhoodSearchSort(); #endif diff --git a/SPlisHSPlasH/Simulation.h b/SPlisHSPlasH/Simulation.h index d0f0260c..1ee05db3 100644 --- a/SPlisHSPlasH/Simulation.h +++ b/SPlisHSPlasH/Simulation.h @@ -184,6 +184,7 @@ namespace SPH static int CFL_MIN_TIMESTEPSIZE; static int CFL_MAX_TIMESTEPSIZE; static int ENABLE_Z_SORT; + static int STEPS_PER_Z_SORT; static int KERNEL_METHOD; static int GRAD_KERNEL_METHOD; @@ -304,6 +305,8 @@ namespace SPH Real m_supportRadius; bool m_sim2D; bool m_enableZSort; + unsigned int m_stepsPerZSort; + unsigned int m_counter; std::function m_simulationMethodChanged; int m_boundaryHandlingMethod; std::string m_cachePath; @@ -388,6 +391,8 @@ namespace SPH bool is2DSimulation() { return m_sim2D; } bool zSortEnabled() { return m_enableZSort; } + unsigned int stepsPerZSort() { return m_stepsPerZSort; } + void initKernels(); void setParticleRadius(Real val); diff --git a/SPlisHSPlasH/TimeStep.h b/SPlisHSPlasH/TimeStep.h index 1cb60e1e..0cfce337 100644 --- a/SPlisHSPlasH/TimeStep.h +++ b/SPlisHSPlasH/TimeStep.h @@ -52,6 +52,11 @@ namespace SPH virtual void emittedParticles(FluidModel *model, const unsigned int startIndex) {}; + /** Important: First call m_model->performNeighborhoodSearchSort() + * to call the z_sort of the neighborhood search. + */ + virtual void performNeighborhoodSearchSort() {}; + virtual void saveState(BinaryFileWriter &binWriter) {}; virtual void loadState(BinaryFileReader &binReader) {}; diff --git a/SPlisHSPlasH/WCSPH/TimeStepWCSPH.cpp b/SPlisHSPlasH/WCSPH/TimeStepWCSPH.cpp index 6fd56500..6a18b55d 100644 --- a/SPlisHSPlasH/WCSPH/TimeStepWCSPH.cpp +++ b/SPlisHSPlasH/WCSPH/TimeStepWCSPH.cpp @@ -22,7 +22,6 @@ TimeStepWCSPH::TimeStepWCSPH() : TimeStep() { m_simulationData.init(); - m_counter = 0; m_stiffness = 50.0; m_exponent = 7.0; @@ -72,7 +71,7 @@ void TimeStepWCSPH::step() TimeManager *tm = TimeManager::getCurrent (); const Real h = tm->getTimeStepSize(); - performNeighborhoodSearch(); + sim->performNeighborhoodSearch(); #ifdef USE_PERFORMANCE_OPTIMIZATION precomputeValues(); @@ -145,7 +144,6 @@ void TimeStepWCSPH::reset() { TimeStep::reset(); m_simulationData.reset(); - m_counter = 0; } void TimeStepWCSPH::computePressureAccels(const unsigned int fluidModelIndex) @@ -212,19 +210,9 @@ void TimeStepWCSPH::computePressureAccels(const unsigned int fluidModelIndex) } } -void TimeStepWCSPH::performNeighborhoodSearch() +void TimeStepWCSPH::performNeighborhoodSearchSort() { - if (Simulation::getCurrent()->zSortEnabled()) - { - if (m_counter % 500 == 0) - { - Simulation::getCurrent()->performNeighborhoodSearchSort(); - m_simulationData.performNeighborhoodSearchSort(); - } - m_counter++; - } - - Simulation::getCurrent()->performNeighborhoodSearch(); + m_simulationData.performNeighborhoodSearchSort(); } void TimeStepWCSPH::emittedParticles(FluidModel *model, const unsigned int startIndex) diff --git a/SPlisHSPlasH/WCSPH/TimeStepWCSPH.h b/SPlisHSPlasH/WCSPH/TimeStepWCSPH.h index 598a0e6e..d1ea70b3 100644 --- a/SPlisHSPlasH/WCSPH/TimeStepWCSPH.h +++ b/SPlisHSPlasH/WCSPH/TimeStepWCSPH.h @@ -23,14 +23,11 @@ namespace SPH Real m_exponent; SimulationDataWCSPH m_simulationData; - unsigned int m_counter; /** Determine the pressure accelerations when the pressure is already known. */ void computePressureAccels(const unsigned int fluidModelIndex); - /** Perform the neighborhood search for all fluid particles. - */ - void performNeighborhoodSearch(); + virtual void performNeighborhoodSearchSort(); virtual void emittedParticles(FluidModel *model, const unsigned int startIndex); virtual void initParameters(); diff --git a/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.cpp b/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.cpp index cccabd72..80e6d5d9 100644 --- a/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.cpp +++ b/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.cpp @@ -41,22 +41,18 @@ PBDWrapper::PBDWrapper() m_sceneName = ""; m_sceneFileName = ""; m_dampingCoeff = 0.0; - m_timeStep = new PBD::TimeStepController(); - m_timeStep->init(); m_model.init(); PBD::Simulation::getCurrent()->setModel(&m_model); } PBDWrapper::~PBDWrapper() { - delete PBD::TimeManager::getCurrent(); - delete m_timeStep; + delete PBD::Simulation::getCurrent(); } void PBDWrapper::reset() { - m_model.reset(); - m_timeStep->reset(); + PBD::Simulation::getCurrent()->reset(); } @@ -68,7 +64,7 @@ PBDWrapper::~PBDWrapper() PBD::TimeManager::getCurrent()->setTimeStepSize(SPH::TimeManager::getCurrent()->getTimeStepSize()); PBD::TimeManager::getCurrent()->setTime(SPH::TimeManager::getCurrent()->getTime()); - m_timeStep->step(m_model); + PBD::Simulation::getCurrent()->getTimeStep()->step(m_model); for (unsigned int i = 0; i < pd.size(); i++) { @@ -164,6 +160,13 @@ void PBDWrapper::readScene(const std::string &sceneFileName, const std::vector< m_sceneName = data.m_sceneName; PBD::Simulation *sim = PBD::Simulation::getCurrent(); + loader.readParameterObject(sim); + loader.readParameterObject(sim->getModel()); + loader.readParameterObject(sim->getTimeStep()); + if (sim->getTimeStep()->getCollisionDetection() != nullptr) + loader.readParameterObject(sim->getTimeStep()->getCollisionDetection()); + + sim->setVecValue(PBD::Simulation::GRAVITATION, &data.m_gravity[0]); ////////////////////////////////////////////////////////////////////////// @@ -658,12 +661,12 @@ void PBDWrapper::initModel (const Real timeStepSize) { PBD::TimeManager::getCurrent ()->setTimeStepSize(timeStepSize); - m_timeStep->setCollisionDetection(m_model, &m_cd); + PBD::Simulation::getCurrent()->getTimeStep()->setCollisionDetection(m_model, &m_cd); } -PBD::TimeStepController & PBDWrapper::getTimeStepController() +PBD::TimeStepController& PBDWrapper::getTimeStepController() { - return *m_timeStep; + return *(PBD::TimeStepController*) PBD::Simulation::getCurrent()->getTimeStep(); } void PBDWrapper::initTriangleModelConstraints() diff --git a/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.h b/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.h index 49e821e4..4063e185 100644 --- a/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.h +++ b/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.h @@ -17,7 +17,6 @@ class PBDWrapper protected: PBD::SimulationModel m_model; PBD::CubicSDFCollisionDetection m_cd; - PBD::TimeStepController *m_timeStep; short m_clothSimulationMethod = 2; short m_solidSimulationMethod = 2; diff --git a/Tests/ReadWriteState/ReadWriteStateTests.cpp b/Tests/ReadWriteState/ReadWriteStateTests.cpp index 6348be55..e1ca0214 100644 --- a/Tests/ReadWriteState/ReadWriteStateTests.cpp +++ b/Tests/ReadWriteState/ReadWriteStateTests.cpp @@ -333,6 +333,7 @@ TEST_CASE("Read/Write state file tests", "[read_write_state]") const bool sim2D = sim->getValue(Simulation::SIM_2D); const bool enableZSort = sim->getValue(Simulation::ENABLE_Z_SORT); + const bool stepsPerZSort = sim->getValue(Simulation::STEPS_PER_Z_SORT); const Real particleRadius = sim->getValue(Simulation::PARTICLE_RADIUS); const Vector3r gravitation(sim->getVecValue(Simulation::GRAVITATION)); const int cflMethod = sim->getValue(Simulation::CFL_METHOD); @@ -365,6 +366,7 @@ TEST_CASE("Read/Write state file tests", "[read_write_state]") sim = Simulation::getCurrent(); sim->setValue(Simulation::CFL_METHOD, 0); sim->setValue(Simulation::ENABLE_Z_SORT, false); + sim->setValue(Simulation::STEPS_PER_Z_SORT, 123); base->getBoundarySimulator()->initBoundaryData(); base->loadState(stateFile); @@ -407,6 +409,7 @@ TEST_CASE("Read/Write state file tests", "[read_write_state]") REQUIRE(sim2D == sim->getValue(Simulation::SIM_2D)); REQUIRE(enableZSort == sim->getValue(Simulation::ENABLE_Z_SORT)); + REQUIRE(stepsPerZSort == sim->getValue(Simulation::STEPS_PER_Z_SORT)); REQUIRE(particleRadius == sim->getValue(Simulation::PARTICLE_RADIUS)); const Vector3r gravitation2(sim->getVecValue(Simulation::GRAVITATION)); REQUIRE(gravitation == gravitation2); diff --git a/version.txt b/version.txt index a3ebb9f5..53fdb123 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.13.0 \ No newline at end of file +2.13.1 \ No newline at end of file