### Build and Install Python Bindings from Source Source: https://splishsplash.readthedocs.io/en/latest/_sources/build_from_source.md.txt Use these commands in the project root to build the wheel and install the package. It is recommended to use a virtual environment. ```bash git clone https://github.com/InteractiveComputerGraphics/SPlisHSPlasH.git cd SPlisHSPlasH python setup.py bdist_wheel pip install build/dist/pySPlisHSPlasH-2.8.3-cp37-cp37m-win_amd64.whl ``` -------------------------------- ### Verify Installation Source: https://splishsplash.readthedocs.io/en/latest/_sources/py_getting_started.md.txt Command to verify the library is correctly installed. ```shell python -c "import pysplishsplash" ``` -------------------------------- ### Install Linux Dependencies Source: https://splishsplash.readthedocs.io/en/latest/_sources/build_from_source.md.txt Install essential build tools and libraries on Ubuntu. ```bash sudo apt install git cmake xorg-dev freeglut3-dev build-essential ``` -------------------------------- ### MeshSkinning Command Line Example Source: https://splishsplash.readthedocs.io/en/latest/MeshSkinning.html Example of using the MeshSkinning tool with scene file input, enabling object splitting and overwriting existing files. ```bash MeshSkinning --splitting --overwrite --scene ..\data\Scenes\Beam.json ``` -------------------------------- ### Build and Install Wheel Source: https://splishsplash.readthedocs.io/en/latest/_sources/py_getting_started.md.txt Commands to build a wheel file for development purposes and install it. ```shell cd SPlisHSPlasH python setup.py bdist_wheel pip install -I build/dist/*.whl ``` -------------------------------- ### Install Python Bindings via Wheel Source: https://splishsplash.readthedocs.io/en/latest/_sources/build_from_source.md.txt Build and install the Python package from source. ```bash git clone https://github.com/InteractiveComputerGraphics/SPlisHSPlasH.git cd SPlisHSPlasH python setup.py bdist_wheel pip install build/dist/*.whl ``` ```bash pip install git+https://github.com/InteractiveComputerGraphics/SPlisHSPlasH.git ``` -------------------------------- ### CohesionKernel Setup Source: https://splishsplash.readthedocs.io/en/latest/_sources/api/program_listing_file_SPlisHSPlasH_SPHKernels.h.rst.txt Initializes the Cohesion kernel parameters. ```cpp class CohesionKernel { protected: static Real m_radius; static Real m_k; static Real m_c; static Real m_W_zero; public: static Real getRadius() { return m_radius; } static void setRadius(Real val) { m_radius = val; const Real pi = static_cast(M_PI); m_k = static_cast(32.0) / (pi*pow(m_radius, static_cast(9.0))); ``` -------------------------------- ### FoamGenerator Example Usage Source: https://splishsplash.readthedocs.io/en/latest/_sources/FoamGenerator.md.txt This example demonstrates how to use the FoamGenerator tool to process a fluid simulation particle file and generate foam particles, specifying input and output paths, start and end frames, particle radius, and foam scale. ```bash FoamGenerator -s 1 -e 500 -r 0.025 --foamscale 1000 -i output\DamBreakModelDragons\partio\ParticleData_Fluid_#.bgeo -o output\DamBreakModelDragons\foam\foam_#.bgeo ``` -------------------------------- ### Install Dependencies Source: https://splishsplash.readthedocs.io/en/latest/_sources/py_getting_started.md.txt Command to install required dependencies like numpy. ```shell pip install numpy ``` -------------------------------- ### Install Python Bindings via Pip Source: https://splishsplash.readthedocs.io/en/latest/_sources/build_from_source.md.txt A single command to install the bindings directly from the repository. Note that this method prevents incremental rebuilds. ```bash pip install git+https://github.com/InteractiveComputerGraphics/SPlisHSPlasH.git ``` -------------------------------- ### Example SplishSplash Python Script Source: https://splishsplash.readthedocs.io/en/latest/_sources/py_embedded_python.md.txt A comprehensive example script demonstrating initialization, step, reset, and custom command functions. It imports necessary modules, defines global variables, and interacts with the simulator's time and fluid models. ```python import splishsplash as sph import numpy as np counter = 0 function_list = ['command', 'command2'] def init(base): global counter print("init test") counter = 1 def step(): global counter sim = sph.Simulation.getCurrent() fluid = sim.getFluidModel(0) tm = sph.TimeManager.getCurrent() print(fluid.getPosition(0)) print(tm.getTime()) print(counter) counter += 1 print("---") def reset(): print("reset test") def command(): print("tst cmd") def command2(): print("tst cmd2") ``` -------------------------------- ### Developer Guide Source: https://splishsplash.readthedocs.io/en/latest/index.html Information for developers on installing, configuring, and extending SPlisHSPlasH. ```APIDOC ## Developer Guide ### Installation Instructions - **Linux (Ubuntu Fresh Install)** - **Windows (Visual Studio)** ### CMake Options Configuration options for building SPlisHSPlasH: - USE_DOUBLE_PRECISION - USE_AVX - USE_OpenMP - USE_GPU_NEIGHBORHOOD_SEARCH - USE_IMGUI - USE_PYTHON_BINDINGS - USE_DEBUG_TOOLS ### Software Architecture Overview of key SPlisHSPlasH classes: - The Simulation class - The TimeStep class - The FluidModel class - The BoundaryModel class ### Implementing New Features - **New non-pressure force method**: Creating and registering new force methods. - **New particle/rigid body data exporter**: Creating and registering custom exporters, including Python implementation. - **Creating Pressure Solvers**: Creating and registering new pressure solver classes. ### Macros Details on macros for common operations: - Looping over fluid neighbors - Looping over boundaries - AVX variants ``` -------------------------------- ### GUI Parameter Setup Source: https://splishsplash.readthedocs.io/en/latest/_sources/api/program_listing_file_SPlisHSPlasH_SurfaceTension_SurfaceTension_ZorillaRitter2020.h.rst.txt Template and specific functions for setting up GUI elements and callbacks for parameters. ```APIDOC ## GUI Parameter Setup ### Description Template and specific functions for setting up GUI elements and callbacks for parameters. ### Methods - **setupGUIParam(int& PARAMID, std::string name, std::string group, std::string description, T* val)** - Template function to set up a numeric GUI parameter. - **setupGUIEnum(int& PARAMID, std::string name, std::string group, std::string description, std::vector> enum_ids, const GenParam::ParameterBase::GetFunc& getter, const GenParam::ParameterBase::SetFunc& setter)** - Sets up an enum type GUI parameter. ``` -------------------------------- ### Python Bindings (pySPlisHSPlasH) Source: https://splishsplash.readthedocs.io/en/latest/index.html Documentation for the Python bindings of the SPlisHSPlasH library, including installation, usage, and examples. ```APIDOC ## pySPlisHSPlasH ### Description Python bindings for the SPlisHSPlasH library, enabling users to control simulations and access data from Python. ### Requirements - Python installed - SPlisHSPlasH library compiled with Python bindings enabled. ### Installation Instructions for installing the pySPlisHSPlasH package. ### Usage Examples - **Minimal Working Example**: Demonstrates a basic simulation setup. - **SPHSimulator.py**: Details on using the SPHSimulator class. - **Modifying Other Properties**: How to alter simulation parameters via Python. ### Creating Scenes with Python - **Loading the empty scene** - **Recreating the double dam break scenario** - **Putting it all together** - **Changing parameters of the simulation** - **Loading a scene from file** ### Restrictions Information on any limitations of the Python bindings. ``` -------------------------------- ### Setup GUI Parameters for Surface Tension Source: https://splishsplash.readthedocs.io/en/latest/_sources/api/program_listing_file_SPlisHSPlasH_SurfaceTension_SurfaceTension_ZorillaRitter2020.cpp.rst.txt Initializes and configures GUI parameters for surface tension models, including coefficients, sampling methods, and normal estimation techniques. Uses std::bind for function callbacks. ```cpp void SurfaceTension_ZorillaRitter2020::initParameters() { using enumGet = GenParam::ParameterBase::GetFunc; using enumSet = GenParam::ParameterBase::SetFunc; NonPressureForceBase::initParameters(); SURFACE_TENSION = createNumericParameter("surfaceTension", "Surface tension coefficient", &m_surfaceTension); setGroup(SURFACE_TENSION, "Fluid Model|Surface tension"); setDescription(SURFACE_TENSION, "Coefficient for the surface tension computation"); RealParameter* rparam = static_cast(getParameter(SURFACE_TENSION)); rparam->setMinValue(0.0); const string grp19 = "Fluid Model|Surface tension"; // "Surface tension ZR19"; const string grp20 = "Fluid Model|Surface tension"; // "Surface tension ZR20"; enumGet getVersionFct = std::bind( &SurfaceTension_ZorillaRitter2020::getVersionMethod, this ); enumSet setVersionFct = std::bind( &SurfaceTension_ZorillaRitter2020::setVersionMethod, this, std::placeholders::_1 ); setupGUIEnum(VERSION, "version", "Fluid Model|Surface tension", "Method or extended method.", { { "V2019", &ENUM_VERSION_V2019 }, { "V2020", &ENUM_VERSION_V2020 } }, getVersionFct, setVersionFct ); // 2019 & 2020 setupGUIParam (CSD, "Csd (19)", grp19, "Samples per Second.", &m_Csd); setupGUIParam(R2MULT, "r-ratio (19)", grp19, "R1 to R2 ratio.", &m_r2mult); setupGUIParam(TAU, "tau (19)", grp19, "Smoothing factor tau.", &m_tau); setupGUIParam(CLASS_D, "d (19)", grp19, "Classifier constant d.", &m_class_d); // 2020 enumGet getSamplingFct = std::bind(&SurfaceTension_ZorillaRitter2020::getSamplingMethod, this); enumSet setSamplingFct = std::bind(&SurfaceTension_ZorillaRitter2020::setSamplingMethod, this, std::placeholders::_1); setupGUIEnum(SAMPLING, "sampling (20)", grp20, "Monte Carlo samping method.", { { "Halton", &SAMPLING_HALTON }, { "Rnd", &SAMPLING_RND } }, getSamplingFct, setSamplingFct); enumGet getNormalFct = std::bind(&SurfaceTension_ZorillaRitter2020::getNormalMethod, this); enumSet setNormalFct = std::bind(&SurfaceTension_ZorillaRitter2020::setNormalMethod, this, std::placeholders::_1); setupGUIEnum(NORMAL_MODE, "normal-mode (20)", grp20, "Normal estimation method.", { { "PCA", &NORMAL_PCA}, { "Monte Carlo", &NORMAL_MC}, { "Mix", &NORMAL_MIX} }, getNormalFct, setNormalFct); setupGUIParam (FIX_SAMPLES, "MCSamples (20)", grp20, "Fixed nr of MC samples per step.", &m_CsdFix); setupGUIParam(PCA_CUR_MIX, "PcaMixCur (20)", grp20, "Factor to mix-in pca curvature.", &m_pca_C_mix); setupGUIParam(PCA_NRM_MIX, "PcaMixNrm (20)", grp20, "Factor to mix-in pca normal.", &m_pca_N_mix); TEMPORAL_SMOOTH = createBoolParameter("surfTZRtemporalSmooth" , "temporalSmoothing (20)", &m_temporal_smoothing); setGroup(TEMPORAL_SMOOTH, grp20); setDescription(TEMPORAL_SMOOTH, "Enable temporal smoothing"); } ``` -------------------------------- ### Initialize SPH Simulation Parameters Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_SurfaceTension_SurfaceTension_Jeske2023.cpp.html Initializes simulation parameters such as particle count, fluid models, boundary models, support radius, time step, density, viscosity, and surface tension. This setup is crucial before starting the simulation loop. ```cpp const int numParticles = (int) m_model->numActiveParticles(); Simulation *sim = Simulation::getCurrent(); const unsigned int nFluids = sim->numberOfFluidModels(); const unsigned int nBoundaries = sim->numberOfBoundaryModels(); const unsigned int fluidModelIndex = m_model->getPointSetIndex(); FluidModel *model = m_model; const Real h = sim->getSupportRadius(); const Real h2 = h * h; const Real dt = TimeManager::getCurrent()->getTimeStepSize(); const Real density0 = m_model->getDensity0(); const Real mu = m_viscosity * density0; const Real mub = m_boundaryViscosity * density0; const Real cohesion = m_surfaceTension; const Real adhesion = m_surfaceTensionBoundary; const Real sphereVolume = static_cast(4.0 / 3.0 * M_PI) * h2 * h; const Real radius = sim->getValue(Simulation::PARTICLE_RADIUS); const Real diameter = static_cast(2.0) * radius; const Real diameter2 = diameter * diameter; const Real W_min = sim->W(Vector3r(diameter, 0, 0)); Real d = 10.0; if (sim->is2DSimulation()) d = 8.0; ``` -------------------------------- ### Implement GUI Parameter Setup Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_SurfaceTension_SurfaceTension_ZorillaRitter2020.h.html Provides template-based and enum-based methods for registering GUI parameters. ```cpp template void setupGUIParam(int& PARAMID, std::string name, std::string group, std::string description, T* val) { std::vector tmp; Utilities::StringTools::tokenize(name, tmp, " "); PARAMID = createNumericParameter( "surfTZR" + tmp[0], name, val); setGroup(PARAMID, group); setDescription(PARAMID, description); GenParam::NumericParameter* rparam = static_cast*>(getParameter(PARAMID)); } void setupGUIEnum(int& PARAMID, std::string name, std::string group, std::string description, std::vector> enum_ids, const GenParam::ParameterBase::GetFunc& getter, const GenParam::ParameterBase::SetFunc& setter); ``` -------------------------------- ### Initialize Linear System Solver Source: https://splishsplash.readthedocs.io/en/latest/api/class_s_p_h_1_1_elasticity___kugelstadt2021.html Sets up the solver for the linear system, either by computing a new factorization or loading one from the cache. ```cpp void initSystem() Initialize the solver for the linear system by either computing a factorization or loading a factorization from the cache. ``` -------------------------------- ### Initialize Viscosity Step Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_Viscosity_Viscosity_Weiler2018.cpp.html Entry point for the viscosity step calculation. ```cpp void Viscosity_Weiler2018::step() { const int numParticles = (int) m_model->numActiveParticles(); ``` -------------------------------- ### Run Simulation with GUI Source: https://splishsplash.readthedocs.io/en/latest/_sources/py_getting_started.md.txt Example script to initialize and run the simulator with a graphical user interface. ```python import pysplishsplash as sph def main(): base = sph.Exec.SimulatorBase() base.init() gui = sph.GUI.Simulator_GUI_imgui(base) base.setGui(gui) base.run() if __name__ == "__main__": main() ``` -------------------------------- ### Initialize Material Parameters Source: https://splishsplash.readthedocs.io/en/latest/_sources/api/program_listing_file_SPlisHSPlasH_Utilities_SceneParameterObjects.cpp.rst.txt Sets up material-specific parameters including ID, rendering values, color mapping, and emitter settings. ```cpp void MaterialParameterObject::initParameters() { MATERIAL_ID = createStringParameter("id", "ID", &id); setGroup(MATERIAL_ID, "Material"); setDescription(MATERIAL_ID, "Defines the id of the material. You have to give the same id to a FluidBlock, a FluidModel or an Emitter if they should have the defined material behavior."); MATERIAL_MIN_VAL = createNumericParameter("renderMinValue", "Min. value", &minVal); setGroup(MATERIAL_MIN_VAL, "Material"); setDescription(MATERIAL_MIN_VAL, "Minimum value used for color-coding the color field in the rendering process."); MATERIAL_MAX_VAL = createNumericParameter("renderMaxValue", "Max. value", &maxVal); setGroup(MATERIAL_MAX_VAL, "Material"); setDescription(MATERIAL_MAX_VAL, "Maximum value used for color-coding the color field in the rendering process."); MATERIAL_COLOR_FIELD = createStringParameter("colorField", "Color field", &colorField); setGroup(MATERIAL_COLOR_FIELD, "Material"); setDescription(MATERIAL_COLOR_FIELD, "Choose vector or scalar field for particle coloring."); MATERIAL_COLOR_MAP = createNumericParameter("colorMapType", "Color map type", &colorMapType); setGroup(MATERIAL_COLOR_MAP, "Material"); setDescription(MATERIAL_COLOR_MAP, "Selection of a color map for coloring the scalar/vector field: 0: None, 1 : Jet, 2 : Plasma, 3 : CoolWarm, 4 : BlueWhiteRed, 5 : Seismic"); MATERIAL_VISIBLE = createBoolParameter("visible", "Visible", &visible); setGroup(MATERIAL_VISIBLE, "Material"); setDescription(MATERIAL_VISIBLE, "Defines if fluid phase is rendered."); MATERIAL_MAX_EMITTER_PARTICLES = createNumericParameter("maxEmitterParticles", "Max. emitter particles", &maxEmitterParticles); setGroup(MATERIAL_MAX_EMITTER_PARTICLES, "Material"); setDescription(MATERIAL_MAX_EMITTER_PARTICLES, "Maximum number of particles the emitter generates. Note that reused particles are not counted here."); MATERIAL_EMITTER_REUSE = createBoolParameter("emitterReuseParticles", "Reuse particles (emitter)", &emitterReuseParticles); setGroup(MATERIAL_EMITTER_REUSE, "Material"); setDescription(MATERIAL_EMITTER_REUSE, "Reuse particles if they are outside of the bounding box defined by emitterBoxMin, emitterBoxMax."); MATERIAL_EMITTER_BOX_MIN = createVectorParameter("emitterBoxMin", "Emitter box min.", 3u, emitterBoxMin.data()); setGroup(MATERIAL_EMITTER_BOX_MIN, "Material"); setDescription(MATERIAL_EMITTER_BOX_MIN, "Minimum coordinates of an axis-aligned box (used in combination with emitterReuseParticles)."); MATERIAL_EMITTER_BOX_MAX = createVectorParameter("emitterBoxMax", "Emitter box max.", 3u, emitterBoxMax.data()); setGroup(MATERIAL_EMITTER_BOX_MAX, "Material"); setDescription(MATERIAL_EMITTER_BOX_MAX, "Maximum coordinates of an axis-aligned box (used in combination with emitterReuseParticles)."); } ``` -------------------------------- ### Install SPlisHSPlasH with Python Bindings Source: https://splishsplash.readthedocs.io/en/latest/_sources/getting_started.md.txt Clone the SPlisHSPlasH repository and install the Python bindings using pip. It is recommended to use a virtual environment. ```shell git clone https://github.com/InteractiveComputerGraphics/SPlisHSPlasH.git pip install SPlisHSPlasH/ ``` -------------------------------- ### Adjust Pressure Rho2 for Warm Start Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_DFSPH_TimeStepDFSPH.cpp.html Adjusts the pressure_rho2 values by multiplying with h^2 when warm start is enabled. This normalizes pressure values. ```cpp #ifdef USE_WARMSTART for (unsigned int fluidModelIndex = 0; fluidModelIndex < nFluids; fluidModelIndex++) { FluidModel* model = sim->getFluidModel(fluidModelIndex); const int numParticles = (int)model->numActiveParticles(); #pragma omp parallel default(shared) { #pragma omp for schedule(static) for (int i = 0; i < numParticles; i++) { // Multiply by h^2, the time step size has to be removed // to make the pressure value independent // of the time step size m_simulationData.getPressureRho2(fluidModelIndex, i) *= h2; } } } #endif ``` -------------------------------- ### Install SPlisHSPlasH using Pip Source: https://splishsplash.readthedocs.io/en/latest/py_getting_started.html Install SPlisHSPlasH using pip. Ensure you are one directory above the cloned source directory and that the trailing slash is present. ```bash pip install SPlisHSPlasH/ ``` -------------------------------- ### Create a simulation script Source: https://splishsplash.readthedocs.io/en/latest/py_embedded_python.html A complete example script demonstrating how to import the splishsplash module, manage state, and implement the required lifecycle functions. ```python import splishsplash as sph import numpy as np counter = 0 function_list = ['command', 'command2'] def init(base): global counter print("init test") counter = 1 def step(): global counter sim = sph.Simulation.getCurrent() fluid = sim.getFluidModel(0) tm = sph.TimeManager.getCurrent() print(fluid.getPosition(0)) print(tm.getTime()) print(counter) counter += 1 print("---") def reset(): print("reset test") def command(): print("tst cmd") def command2(): print("tst cmd2") ``` -------------------------------- ### Custom Exporter Example in Python Source: https://splishsplash.readthedocs.io/en/latest/_sources/implement_exporter.md.txt An example demonstrating how to implement a custom exporter using the SPlisHSPlasH Python interface. Refer to `pySPlisHSPlasH/examples/custom_exporter.py` for the full implementation. ```python # Example usage of a custom exporter in Python # See pySPlisHSPlasH/examples/custom_exporter.py for full implementation. ``` -------------------------------- ### Bender2019 Boundary Handling Setup Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_SurfaceTension_SurfaceTension_Jeske2023.cpp.html Initializes parameters for the Bender2019 boundary handling method, including calculating orthogonal vectors for surface tension calculations. ```cpp forall_volume_maps( const Vector3r xixj = xi - xj; Vector3r normal = -xixj; const Real nl = normal.norm(); if (nl > static_cast(0.0001)) { normal /= nl; Vector3r t1; Vector3r t2; MathFunctions::getOrthogonalVectors(normal, t1, t2); const Real dist = surf_tens->m_tangentialDistanceFactor * h; ``` -------------------------------- ### Compute Density Change and Pressure Rho2_V Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_DFSPH_TimeStepDFSPH.cpp.html Calculates the density change and initializes pressure values for the DFSPH solver. Handles warm start and non-warm start scenarios. Requires OpenMP for parallel processing. ```cpp const int numParticles = (int)model->numActiveParticles(); #pragma omp parallel default(shared) { #pragma omp for schedule(static) for (int i = 0; i < numParticles; i++) { // Compute rho_adv,i^(0) (see equation (9) in Section 3.2 [BK17]) // using the velocities after the non-pressure forces were applied. computeDensityChange(fluidModelIndex, i, h); Real densityAdv = m_simulationData.getDensityAdv(fluidModelIndex, i); densityAdv = max(densityAdv, static_cast(0.0)); unsigned int numNeighbors = 0; for (unsigned int pid = 0; pid < sim->numberOfPointSets(); pid++) numNeighbors += sim->numberOfNeighbors(fluidModelIndex, pid, i); // in case of particle deficiency do not perform a divergence solve if (!sim->is2DSimulation()) { if (numNeighbors < 20) densityAdv = 0.0; } else { if (numNeighbors < 7) densityAdv = 0.0; } // In equation (11) [BK17] we have to multiply the divergence // error with the factor divided by h. Hence, we multiply the factor // directly by 1/h here. m_simulationData.getFactor(fluidModelIndex, i) *= invH; // For the warm start we use 0.5 times the old pressure value. // Divide the value by h. We multiplied it by h at the end of // the last time step to make it independent of the time step size. #ifdef USE_WARMSTART_V if (densityAdv > 0.0) m_simulationData.getPressureRho2_V(fluidModelIndex, i) = static_cast(0.5) * min(m_simulationData.getPressureRho2_V(fluidModelIndex, i), static_cast(0.5)) * invH; else m_simulationData.getPressureRho2_V(fluidModelIndex, i) = 0.0; #else // If we don't use a warm start, directly compute a pressure value // by multiplying the divergence error with the factor. m_simulationData.getPressureRho2_V(fluidModelIndex, i) = densityAdv * m_simulationData.getFactor(fluidModelIndex, i); #endif } } } ``` -------------------------------- ### Initialize Fluid Model Source: https://splishsplash.readthedocs.io/en/latest/_sources/api/program_listing_file_SPlisHSPlasH_FluidModel.cpp.rst.txt Sets up the fluid model with initial particle data and registers the point set for neighborhood search. ```cpp void FluidModel::initModel(const std::string &id, const unsigned int nFluidParticles, Vector3r* fluidParticles, Vector3r* fluidVelocities, unsigned int* fluidObjectIds, const unsigned int nMaxEmitterParticles) { m_id = id; init(); releaseFluidParticles(); resizeFluidParticles(nFluidParticles + nMaxEmitterParticles); // copy fluid positions #pragma omp parallel default(shared) { #pragma omp for schedule(static) for (int i = 0; i < (int)nFluidParticles; i++) { getPosition0(i) = fluidParticles[i]; getPosition(i) = fluidParticles[i]; getVelocity0(i) = fluidVelocities[i]; getVelocity(i) = fluidVelocities[i]; getAcceleration(i).setZero(); m_density[i] = 0.0; m_particleId[i] = i; m_objectId[i] = fluidObjectIds[i]; m_objectId0[i] = fluidObjectIds[i]; if (m_particleState[i] != ParticleState::Fixed) m_particleState[i] = ParticleState::Active; } } // set IDs for emitted particles for (unsigned int i = nFluidParticles; i < (nFluidParticles + nMaxEmitterParticles); i++) { m_particleId[i] = i; m_objectId[i] = 0; } // initialize masses initMasses(); // Fluids NeighborhoodSearch *neighborhoodSearch = Simulation::getCurrent()->getNeighborhoodSearch(); m_pointSetIndex = neighborhoodSearch->add_point_set(&getPosition(0)[0], nFluidParticles, true, true, true, this); m_numActiveParticles0 = nFluidParticles; m_numActiveParticles = m_numActiveParticles0; } ``` -------------------------------- ### Initialize Surface Tension Matrix-Vector Product Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_SurfaceTension_SurfaceTension_Jeske2023.cpp.html Sets up parameters for the Jeske2023 surface tension model matrix-vector product calculation. ```cpp void SurfaceTension_Jeske2023::matrixVecProd(const Real *vec, Real *result, void *userData) { Simulation *sim = Simulation::getCurrent(); SurfaceTension_Jeske2023 *surf_tens = (SurfaceTension_Jeske2023 *) userData; FluidModel *model = surf_tens->getModel(); const unsigned int numParticles = model->numActiveParticles(); const unsigned int fluidModelIndex = model->getPointSetIndex(); const unsigned int nFluids = sim->numberOfFluidModels(); const unsigned int nBoundaries = sim->numberOfBoundaryModels(); const Real h = sim->getSupportRadius(); const Real h2 = h * h; const Real dt = TimeManager::getCurrent()->getTimeStepSize(); const Real density0 = model->getDensity0(); const Real mu = surf_tens->m_viscosity * density0; const Real mub = surf_tens->m_boundaryViscosity * density0; const Real sphereVolume = static_cast(4.0 / 3.0 * M_PI) * h2 * h; const Real cohesion = surf_tens->m_surfaceTension; const Real adhesion = surf_tens->m_surfaceTensionBoundary; const Real mu_xsph = surf_tens->m_xsph; const Real radius = sim->getValue(Simulation::PARTICLE_RADIUS); const Real diameter = static_cast(2.0) * radius; const Real diameter2 = diameter * diameter; const Real W_min = sim->W(Vector3r(diameter, 0, 0)); Real d = 10.0; if (sim->is2DSimulation()) d = 8.0; #pragma omp parallel default(shared) { ``` -------------------------------- ### Adjust Pressure Rho2_V for Warm Start Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_DFSPH_TimeStepDFSPH.cpp.html Adjusts the PressureRho2_V values by multiplying with h, specifically for the warm start scenario to make pressure values independent of time step size. Requires OpenMP for parallel processing. ```cpp #ifdef USE_WARMSTART_V for (unsigned int fluidModelIndex = 0; fluidModelIndex < nFluids; fluidModelIndex++) { FluidModel* model = sim->getFluidModel(fluidModelIndex); const int numParticles = (int)model->numActiveParticles(); #pragma omp parallel default(shared) { #pragma omp for schedule(static) for (int i = 0; i < numParticles; i++) { // Multiply by h, the time step size has to be removed // to make the pressure value independent // of the time step size m_simulationData.getPressureRho2_V(fluidModelIndex, i) *= h; } } } #endif ``` -------------------------------- ### Template Function for GUI Parameter Setup Source: https://splishsplash.readthedocs.io/en/latest/_sources/api/program_listing_file_SPlisHSPlasH_SurfaceTension_SurfaceTension_ZorillaRitter2020.h.rst.txt A template function to set up GUI numeric parameters. It tokenizes the name, creates the parameter, and sets its group and description. ```cpp template void setupGUIParam(int& PARAMID, std::string name, std::string group, std::string description, T* val) { std::vector tmp; Utilities::StringTools::tokenize(name, tmp, " "); PARAMID = createNumericParameter( "surfTZR" + tmp[0], name, val); setGroup(PARAMID, group); setDescription(PARAMID, description); GenParam::NumericParameter* rparam = static_cast*>(getParameter(PARAMID)); } ``` -------------------------------- ### Get Density0 Source: https://splishsplash.readthedocs.io/en/latest/_sources/api/program_listing_file_SPlisHSPlasH_FluidModel.h.rst.txt Returns the reference density of the fluid. ```cpp FORCE_INLINE Real getDensity0() const { return m_density0; } ``` -------------------------------- ### Initialize TimeStepPF Parameters Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_PF_TimeStepPF.cpp.html Sets up and registers simulation parameters for the Projective Fluids solver, including iterations, error, and stiffness. ```cpp void TimeStepPF::initParameters() { TimeStep::initParameters(); SOLVER_ITERATIONS = createNumericParameter("iterations", "Iterations", &m_iterations); setGroup(SOLVER_ITERATIONS, "Simulation|Projective Fluids"); setDescription(SOLVER_ITERATIONS, "Iterations required by the pressure solver."); getParameter(SOLVER_ITERATIONS)->setReadOnly(true); MIN_ITERATIONS = createNumericParameter("minIterations", "Min. iterations", &m_minIterations); setGroup(MIN_ITERATIONS, "Simulation|Projective Fluids"); setDescription(MIN_ITERATIONS, "Minimal number of iterations of the pressure solver."); static_cast*>(getParameter(MIN_ITERATIONS))->setMinValue(0); MAX_ITERATIONS = createNumericParameter("maxIterations", "Max. iterations", &m_maxIterations); setGroup(MAX_ITERATIONS, "Simulation|Projective Fluids"); setDescription(MAX_ITERATIONS, "Maximal number of iterations of the pressure solver."); static_cast*>(getParameter(MAX_ITERATIONS))->setMinValue(1); MAX_ERROR = createNumericParameter("maxError", "Max. error", &m_maxError); setGroup(MAX_ERROR, "Simulation|Projective Fluids"); setDescription(MAX_ERROR, "Maximal error."); static_cast(getParameter(MAX_ERROR))->setMinValue(static_cast(1e-12)); STIFFNESS = createNumericParameter("stiffness", "Stiffness", &m_stiffness); setGroup(STIFFNESS, "Simulation|Projective Fluids"); setDescription(STIFFNESS, "Stiffness coefficient."); } ``` -------------------------------- ### Run MeshSkinning with Scene File Source: https://splishsplash.readthedocs.io/en/latest/_sources/MeshSkinning.md.txt Execute the MeshSkinning tool using a scene file for all settings. Ensure the '--splitting' and '--overwrite' flags are used if applicable. ```bash MeshSkinning --splitting --overwrite --scene ..\data\Scenes\Beam.json ``` -------------------------------- ### Run Simulator CLI Source: https://splishsplash.readthedocs.io/en/latest/_sources/py_getting_started.md.txt Commands to launch the simulator or view help options. ```shell splash ``` ```shell splash --help ``` -------------------------------- ### GET /simulation/method Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_SurfaceTension_SurfaceTension_ZorillaRitter2020.h.html Retrieves the current simulation version method. ```APIDOC ## GET /simulation/method ### Description Returns the integer representation of the current simulation step version. ### Method GET ### Endpoint /simulation/method ### Response #### Success Response (200) - **version** (int) - The current simulation method version. ``` -------------------------------- ### Execute Simulation Step Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_Elasticity_Elasticity_Peer2018.cpp.html Starts the timing for the elasticity simulation step. ```cpp void Elasticity_Peer2018::step() { START_TIMING("Elasticity_Peer2018") const unsigned int numParticles = m_model->numActiveParticles(); ``` -------------------------------- ### GET /simulation/normal-method Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_SurfaceTension_SurfaceTension_ZorillaRitter2020.h.html Retrieves the current normal vector calculation method. ```APIDOC ## GET /simulation/normal-method ### Description Returns the integer representation of the current normal vector calculation method (e.g., PCA, Monte Carlo, Mixed). ### Method GET ### Endpoint /simulation/normal-method ### Response #### Success Response (200) - **normal_method** (int) - The current normal method identifier. ``` -------------------------------- ### Initialize Boundary Parameters Source: https://splishsplash.readthedocs.io/en/latest/_sources/api/program_listing_file_SPlisHSPlasH_Utilities_SceneParameterObjects.cpp.rst.txt Sets up various parameters for a boundary object, including file paths, transformations, and physical properties. Use this function to configure boundary behavior and appearance. ```cpp int BoundaryParameterObject::BOUNDARY_SCALE = -1; int BoundaryParameterObject::BOUNDARY_DYNAMIC = -1; int BoundaryParameterObject::BOUNDARY_IS_WALL = -1; int BoundaryParameterObject::BOUNDARY_COLOR = -1; int BoundaryParameterObject::BOUNDARY_MAP_FILE = -1; int BoundaryParameterObject::BOUNDARY_MAP_INVERT = -1; int BoundaryParameterObject::BOUNDARY_MAP_THICKNESS = -1; int BoundaryParameterObject::BOUNDARY_MAP_RESOLUTION = -1; int BoundaryParameterObject::BOUNDARY_SAMPLING_MODE = -1; int BoundaryParameterObject::BOUNDARY_IS_ANIMATED = -1; void BoundaryParameterObject::initParameters() { BOUNDARY_SAMPLES_FILE = createStringParameter("particleFile", "Particle file", &samplesFile); setGroup(BOUNDARY_SAMPLES_FILE, "Boundary"); setDescription(BOUNDARY_SAMPLES_FILE, "Path to a partio file which contains a surface sampling of the body. Note that the surface sampling is done automatically if this parameter is missing."); BOUNDARY_MESH_FILE = createStringParameter("geometryFile", "Geometry file", &meshFile); setGroup(BOUNDARY_MESH_FILE, "Boundary"); setDescription(BOUNDARY_MESH_FILE, "Path to a OBJ/PLY file which contains the geometry of the body."); BOUNDARY_TRANSLATION = createVectorParameter("translation", "Translation", 3u, translation.data()); setGroup(BOUNDARY_TRANSLATION, "Boundary"); setDescription(BOUNDARY_TRANSLATION, "Translation vector of the rigid body."); BOUNDARY_AXIS = createVectorParameter("rotationAxis", "Rotation axis", 3u, axis.data()); setGroup(BOUNDARY_AXIS, "Boundary"); setDescription(BOUNDARY_AXIS, "Axis used to rotate the rigid body after loading."); BOUNDARY_ANGLE = createNumericParameter("rotationAngle", "Rotation angle", &angle); setGroup(BOUNDARY_ANGLE, "Boundary"); setDescription(BOUNDARY_ANGLE, "Rotation angle for the initial rotation of the rigid body."); BOUNDARY_SCALE = createVectorParameter("scale", "Scale", 3u, scale.data()); setGroup(BOUNDARY_SCALE, "Boundary"); setDescription(BOUNDARY_SCALE, "Scaling vector of the rigid body."); BOUNDARY_DYNAMIC = createBoolParameter("isDynamic", "Dynamic", &dynamic); setGroup(BOUNDARY_DYNAMIC, "Boundary"); setDescription(BOUNDARY_DYNAMIC, "Defines if the body is static or dynamic."); BOUNDARY_IS_WALL = createBoolParameter("isWall", "Wall", &isWall); setGroup(BOUNDARY_IS_WALL, "Boundary"); setDescription(BOUNDARY_IS_WALL, "Defines if this is a wall. Walls are typically not rendered. This is the only difference."); BOUNDARY_COLOR = createVectorParameter("color", "Color", 4u, color.data()); setGroup(BOUNDARY_COLOR, "Boundary"); setDescription(BOUNDARY_COLOR, "RGBA color of the body."); BOUNDARY_MAP_FILE = createStringParameter("mapFile", "Map file", &mapFile); setGroup(BOUNDARY_MAP_FILE, "Boundary"); setDescription(BOUNDARY_MAP_FILE, "Path to a volume/density map file which contains a volume/density map of the body. Note that the map is generated automatically if this parameter is missing."); BOUNDARY_MAP_INVERT = createBoolParameter("mapInvert", "Invert map", &mapInvert); setGroup(BOUNDARY_MAP_INVERT, "Boundary"); setDescription(BOUNDARY_MAP_INVERT, "Invert the map when using density or volume maps, flips inside/outside."); BOUNDARY_MAP_THICKNESS = createNumericParameter("mapThickness", "Map thickness", &mapThickness); setGroup(BOUNDARY_MAP_THICKNESS, "Boundary"); setDescription(BOUNDARY_MAP_THICKNESS, "Additional thickness of a volume or density map."); BOUNDARY_MAP_RESOLUTION = createVectorParameter("mapResolution", "Map resolution", 3u, mapResolution.data()); setGroup(BOUNDARY_MAP_RESOLUTION, "Boundary"); setDescription(BOUNDARY_MAP_RESOLUTION, " Resolution of a volume or density map."); BOUNDARY_SAMPLING_MODE = createNumericParameter("samplingMode", "Sampling mode", &samplingMode); setGroup(BOUNDARY_SAMPLING_MODE, "Boundary"); setDescription(BOUNDARY_SAMPLING_MODE, "Surface sampling mode. 0 Poisson disk sampling, 1 Regular triangle sampling."); BOUNDARY_IS_ANIMATED = createBoolParameter("isAnimated", "Animated", &isAnimated); setGroup(BOUNDARY_IS_ANIMATED, "Boundary"); setDescription(BOUNDARY_IS_ANIMATED, "Defines if the body is animated (e.g. by a script)."); } ``` -------------------------------- ### GET /simulation/sampling Source: https://splishsplash.readthedocs.io/en/latest/api/program_listing_file_SPlisHSPlasH_SurfaceTension_SurfaceTension_ZorillaRitter2020.h.html Retrieves the current sampling method used for simulations. ```APIDOC ## GET /simulation/sampling ### Description Returns the integer representation of the current sampling method (e.g., Halton, Random). ### Method GET ### Endpoint /simulation/sampling ### Response #### Success Response (200) - **sampling_method** (int) - The current sampling method identifier. ``` -------------------------------- ### Execute VolumeSampling via command line Source: https://splishsplash.readthedocs.io/en/latest/_sources/VolumeSampling.md.txt Run the VolumeSampling executable to convert an OBJ model into a VTK particle file using the specified sampling mode. ```bash VolumeSampling.exe --mode 4 -i ..\data\models\bunny.obj -o bunny.vtk ``` -------------------------------- ### Install Python Bindings Dependencies on Linux Source: https://splishsplash.readthedocs.io/en/latest/_sources/build_from_source.md.txt Prepare the environment for Python bindings using pipx. ```bash sudo apt install python3-dev python3-pip python3-venv python3 -m pip install pipx python3 -m pipx ensurepath ``` -------------------------------- ### SimulationDataDFSPH Accessors Source: https://splishsplash.readthedocs.io/en/latest/api/class_s_p_h_1_1_simulation_data_d_f_s_p_h.html Methods to get and set particle-specific simulation properties. ```APIDOC ## SimulationDataDFSPH Accessors ### Description Methods to access and modify internal simulation variables such as factors, density, and pressure acceleration. ### Parameters #### Path Parameters - **fluidIndex** (unsigned int) - Required - The index of the fluid model. - **i** (unsigned int) - Required - The particle index. ### Methods - **getFactor(fluidIndex, i)** / **setFactor(fluidIndex, i, p)**: Access/Modify factor αi. - **getDensityAdv(fluidIndex, i)** / **setDensityAdv(fluidIndex, i, d)**: Access/Modify advected density. - **getPressureRho2(fluidIndex, i)** / **setPressureRho2(fluidIndex, i, p)**: Access/Modify pρ2 value of the constant density solver. - **getPressureRho2_V(fluidIndex, i)** / **setPressureRho2_V(fluidIndex, i, p)**: Access/Modify pρ2 value of the divergence solver. - **getPressureAccel(fluidIndex, i)** / **setPressureAccel(fluidIndex, i, val)**: Access/Modify pressure acceleration. ``` -------------------------------- ### Get Fields Source: https://splishsplash.readthedocs.io/en/latest/_sources/api/program_listing_file_SPlisHSPlasH_FluidModel.h.rst.txt Returns a constant reference to the vector of all field descriptions. ```cpp const std::vector &getFields() { return m_fields; } ```