Thanks to visit codestin.com
Credit goes to mps-basic.github.io

MPS-Basic
Loading...
Searching...
No Matches
MPS Class Reference

MPS simulation class. More...

#include <mps.hpp>

Collaboration diagram for MPS:

Public Member Functions

 MPS ()=default
 
 MPS (const Input &input, Eigen::Vector3d &gravity, std::unique_ptr< PressureCalculator::Interface > &&pressureCalculator, std::unique_ptr< SurfaceDetector::Interface > &&surfaceDetector)
 
void stepForward ()
 

Public Attributes

Settings settings
 Settings for the simulation.
 
Eigen::Vector3d gravity
 Gravity vector for the simulation.
 
RefValues refValuesForNumberDensity
 Reference values for the simulation ( \(n^0\), \(\lambda^0\))
 
RefValues refValuesForLaplacian
 Reference values for the simulation ( \(n^0\), \(\lambda^0\))
 
RefValues refValuesForGradient
 Reference values for the simulation ( \(n^0\), \(\lambda^0\))
 
Particles particles
 Particles in the simulation.
 
Domain domain {}
 Domain of the simulation.
 
std::unique_ptr< PressureCalculator::InterfacepressureCalculator
 Interface for pressure calculation.
 
double courant {}
 Maximum courant number among all particles.
 

Private Member Functions

void calGravity ()
 calculate gravity term
 
void calViscosity (const double &re)
 calculate viscosity term of Navier-Stokes equation
 
void moveParticle ()
 move particles in prediction step
 
void collision ()
 calculate collision between particles when they are too close
 
void calNumberDensity (const double &re)
 calculate number density of each particle
 
void setBoundaryCondition ()
 set boundary condition of pressure Poisson equation
 
bool isFreeSurface (const Particle &pi)
 
bool isParticleDistributionBiased (const Particle &pi)
 check if particle distribution is biased.
 
void setMinimumPressure (const double &re)
 set minimum pressure for pressure gradient calculation
 
void calPressureGradient (const double &re)
 calculate pressure gradient term
 
void moveParticleUsingPressureGradient ()
 move particles in correction step
 
void calCourant ()
 calculate Courant number
 

Private Attributes

NeighborSearcher neighborSearcher
 Neighbor searcher for neighbor search.
 
std::unique_ptr< SurfaceDetector::InterfacesurfaceDetector
 Interface for free surface detection.
 

Detailed Description

MPS simulation class.

Executes the MPS simulation. This class does not handle the simulation process itself, but only the calculation of the MPS method.

Definition at line 25 of file mps.hpp.

Constructor & Destructor Documentation

◆ MPS() [1/2]

MPS::MPS ( )
default

◆ MPS() [2/2]

MPS::MPS ( const Input & input,
Eigen::Vector3d & gravity,
std::unique_ptr< PressureCalculator::Interface > && pressureCalculator,
std::unique_ptr< SurfaceDetector::Interface > && surfaceDetector )

Definition at line 15 of file mps.cpp.

20 {
21 this->settings = input.settings;
22 this->domain = input.settings.domain;
23 this->particles = input.particles;
24 this->gravity = gravity;
25 this->pressureCalculator = std::move(pressureCalculator);
26 this->surfaceDetector = std::move(surfaceDetector);
28
32}
std::unique_ptr< PressureCalculator::Interface > pressureCalculator
Interface for pressure calculation.
Definition mps.hpp:35
Settings settings
Settings for the simulation.
Definition mps.hpp:27
RefValues refValuesForLaplacian
Reference values for the simulation ( , )
Definition mps.hpp:30
RefValues refValuesForNumberDensity
Reference values for the simulation ( , )
Definition mps.hpp:29
Eigen::Vector3d gravity
Gravity vector for the simulation.
Definition mps.hpp:28
NeighborSearcher neighborSearcher
Neighbor searcher for neighbor search.
Definition mps.hpp:49
std::unique_ptr< SurfaceDetector::Interface > surfaceDetector
Interface for free surface detection.
Definition mps.hpp:50
RefValues refValuesForGradient
Reference values for the simulation ( , )
Definition mps.hpp:31
Particles particles
Particles in the simulation.
Definition mps.hpp:32
Domain domain
Domain of the simulation.
Definition mps.hpp:33
int size() const
Get the number of particles.
Definition particles.cpp:22
Struct for reference values of MPS method.
Definition refvalues.hpp:8
Particles particles
Initial particles arrangement in the simulation.
Definition input.hpp:14
Settings settings
Settings for the simulation.
Definition input.hpp:13
double reMax
Maximum of effective radius.
Definition settings.hpp:60
double particleDistance
Initial distance between particles.
Definition settings.hpp:18
int dim
Dimension of the simulation.
Definition settings.hpp:17
double re_forNumberDensity
Effective radius for number density.
Definition settings.hpp:57
double re_forGradient
Effective radius for gradient.
Definition settings.hpp:58
Domain domain
domain of the simulation
Definition settings.hpp:25
double re_forLaplacian
Effective radius for Laplacian.
Definition settings.hpp:59
Here is the call graph for this function:

Member Function Documentation

◆ stepForward()

void MPS::stepForward ( )

Definition at line 34 of file mps.cpp.

34 {
36 calGravity();
39
41 collision();
42
45 auto pressures = pressureCalculator->calc(particles);
46 for (auto& particle : particles) {
47 particle.pressure = pressures[particle.id];
48 }
49
53
54 // Update pressure again when using EMPS
55 if (auto explicitPressureCalculator = dynamic_cast<PressureCalculator::Explicit*>(pressureCalculator.get())) {
56 auto pressures = explicitPressureCalculator->calc(particles);
57 for (auto& particle : particles) {
58 particle.pressure = pressures[particle.id];
59 }
60 }
61
62 calCourant();
63}
void setMinimumPressure(const double &re)
set minimum pressure for pressure gradient calculation
Definition mps.cpp:178
void calViscosity(const double &re)
calculate viscosity term of Navier-Stokes equation
Definition mps.cpp:76
void moveParticleUsingPressureGradient()
move particles in correction step
Definition mps.cpp:230
void calPressureGradient(const double &re)
calculate pressure gradient term
Definition mps.cpp:203
void moveParticle()
move particles in prediction step
Definition mps.cpp:102
void calCourant()
calculate Courant number
Definition mps.cpp:242
void collision()
calculate collision between particles when they are too close
Definition mps.cpp:113
void calNumberDensity(const double &re)
calculate number density of each particle
Definition mps.cpp:149
void calGravity()
calculate gravity term
Definition mps.cpp:65
void setNeighbors(Particles &particles)
Class for explicit pressure calculation.
Definition explicit.hpp:14
Here is the call graph for this function:
Here is the caller graph for this function:

◆ calGravity()

void MPS::calGravity ( )
private

calculate gravity term

Definition at line 65 of file mps.cpp.

65 {
66#pragma omp parallel for
67 for (auto& p : particles) {
68 if (p.type == ParticleType::Fluid) {
69 p.acceleration += gravity;
70 } else {
71 p.acceleration.setZero();
72 }
73 }
74}
@ Fluid
Fluid particle.
Here is the caller graph for this function:

◆ calViscosity()

void MPS::calViscosity ( const double & re)
private

calculate viscosity term of Navier-Stokes equation

Parameters
reeffective radius \(r_e\)

The viscosity term of the Navier-Stokes equation is calculated as follows:

\[ \nu\langle \nabla^2\mathbf{u}\rangle_i = \nu\frac{2 d}{n^0\lambda^0}\sum_{j\neq i} (\mathbf{u}_j - \mathbf{u}_i) w_{ij} \]

Definition at line 76 of file mps.cpp.

76 {
77 double n0 = refValuesForLaplacian.n0;
78 double lambda = refValuesForLaplacian.lambda;
79 double a = (settings.kinematicViscosity) * (2.0 * settings.dim) / (n0 * lambda);
80
81#pragma omp parallel for
82 for (auto& pi : particles) {
83 if (pi.type != ParticleType::Fluid)
84 continue;
85
86 Eigen::Vector3d viscosityTerm = Eigen::Vector3d::Zero();
87
88 for (auto& neighbor : pi.neighbors) {
89 auto& pj = particles[neighbor.id];
90
91 if (neighbor.distance < settings.re_forLaplacian) {
92 double w = weight(neighbor.distance, re);
93 viscosityTerm += (pj.velocity - pi.velocity) * w;
94 }
95 }
96
97 viscosityTerm *= a;
98 pi.acceleration += viscosityTerm;
99 }
100}
double n0
reference value of number density for source term of pressure Poisson equation
Definition refvalues.hpp:10
double lambda
coefficient for laplacian
Definition refvalues.hpp:11
double kinematicViscosity
Kinematic viscosity.
Definition settings.hpp:28
double weight(double dis, double re)
Wight function for MPS method presented by Koshizuka and Oka, 1996
Definition weight.cpp:5
Here is the call graph for this function:
Here is the caller graph for this function:

◆ moveParticle()

void MPS::moveParticle ( )
private

move particles in prediction step

The position and velocity of each particle are updated as

\[ \mathbf{u}_i^* = \mathbf{u}_i^k + (\nu\langle \nabla^2\mathbf{u}\rangle^k_i+\mathbf{g})\Delta t. \]

Definition at line 102 of file mps.cpp.

102 {
103#pragma omp parallel for
104 for (auto& p : particles) {
105 if (p.type == ParticleType::Fluid) {
106 p.velocity += p.acceleration * settings.dt;
107 p.position += p.velocity * settings.dt;
108 }
109 p.acceleration.setZero();
110 }
111}
double dt
Time step.
Definition settings.hpp:19
Here is the caller graph for this function:

◆ collision()

void MPS::collision ( )
private

calculate collision between particles when they are too close

Definition at line 113 of file mps.cpp.

113 {
114 for (auto& pi : particles) {
115 if (pi.type != ParticleType::Fluid)
116 continue;
117
118 for (auto& neighbor : pi.neighbors) {
119 Particle& pj = particles[neighbor.id];
120 if (pj.type == ParticleType::Fluid && pj.id >= pi.id)
121 continue;
122
123 if (neighbor.distance < settings.collisionDistance) {
124
125 double invMi = pi.inverseDensity();
126 double invMj = pj.inverseDensity();
127 double mass = 1.0 / (invMi + invMj);
128
129 Eigen::Vector3d normal = (pj.position - pi.position).normalized();
130 double relVel = (pj.velocity - pi.velocity).dot(normal);
131 double impulse = 0.0;
132 if (relVel < 0.0)
133 impulse = -(1 + settings.coefficientOfRestitution) * relVel * mass;
134 pi.velocity -= impulse * invMi * normal;
135 pj.velocity += impulse * invMj * normal;
136
137 double depth = settings.collisionDistance - neighbor.distance;
138 double positionImpulse = depth * mass;
139 pi.position -= positionImpulse * invMi * normal;
140 pj.position += positionImpulse * invMj * normal;
141
142 // cerr << "WARNING: Collision between particles " << pi.id << " and " << pj.id << " occurred."
143 // << endl;
144 }
145 }
146 }
147}
Class for particle in MPS method.
Definition particle.hpp:47
double inverseDensity() const
calculate inverse of density for collision
Definition particle.cpp:12
Eigen::Vector3d position
position of the particle
Definition particle.hpp:55
int id
index of the particle
Definition particle.hpp:50
Eigen::Vector3d velocity
velocity of the particle
Definition particle.hpp:56
ParticleType type
type of the particle
Definition particle.hpp:51
double collisionDistance
Distance for collision detection.
Definition settings.hpp:53
double coefficientOfRestitution
Coefficient of restitution.
Definition settings.hpp:54
Here is the call graph for this function:
Here is the caller graph for this function:

◆ calNumberDensity()

void MPS::calNumberDensity ( const double & re)
private

calculate number density of each particle

Parameters
reeffective radius \(r_e\)

Definition at line 149 of file mps.cpp.

149 {
150#pragma omp parallel for
151 for (auto& pi : particles) {
152 pi.numberDensity = 0.0;
153
154 if (pi.type == ParticleType::Ghost)
155 continue;
156
157 for (auto& neighbor : pi.neighbors)
158 pi.numberDensity += weight(neighbor.distance, re);
159 }
160}
@ Ghost
Ghost particle (outside of the domain, not used for calculation)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setBoundaryCondition()

void MPS::setBoundaryCondition ( )
private

set boundary condition of pressure Poisson equation

Definition at line 162 of file mps.cpp.

162 {
163#pragma omp parallel for
164 for (auto& pi : particles) {
165 if (pi.type == ParticleType::Ghost || pi.type == ParticleType::DummyWall) {
166 pi.boundaryCondition = FluidState::Ignored;
167
168 } else { // Fluid particles
169 if (surfaceDetector->isFreeSurface(particles, pi)) {
170 pi.boundaryCondition = FluidState::FreeSurface;
171 } else {
172 pi.boundaryCondition = FluidState::Inner;
173 }
174 }
175 }
176}
@ Inner
inner fluid particle
@ FreeSurface
free surface particle
@ Ignored
Ghost or dummy.
@ DummyWall
Dummy wall particle (pressure is not calculated)

◆ isFreeSurface()

bool MPS::isFreeSurface ( const Particle & pi)
private

◆ isParticleDistributionBiased()

bool MPS::isParticleDistributionBiased ( const Particle & pi)
private

check if particle distribution is biased.

Particle number density can be low even in the fluid region, making the free surface detection based on particle number density vulnerable. Even when a specific particle's the particle number density is lower than criteria, it can be considered as inner particle if the particle distribution around the particle is not biased. In this way we can avoid the free surface detection error. This is based on Khayyer et al. (https://doi.org/10.1016/j.apor.2009.06.003)

Parameters
piParticle to check
Returns
true particle distribution is biased = free surface
false particle distribution is not biased = not free surface

◆ setMinimumPressure()

void MPS::setMinimumPressure ( const double & re)
private

set minimum pressure for pressure gradient calculation

Parameters
reeffective radius \(r_e\)

Definition at line 178 of file mps.cpp.

178 {
179#pragma omp parallel for
180 for (auto& p : particles) {
181 p.minimumPressure = p.pressure;
182 }
183
184 for (auto& pi : particles) {
185 if (pi.type == ParticleType::Ghost || pi.type == ParticleType::DummyWall)
186 continue;
187
188 for (auto& neighbor : pi.neighbors) {
189 Particle& pj = particles[neighbor.id];
191 continue;
192 if (pj.id > pi.id)
193 continue;
194
195 if (neighbor.distance < re) {
196 pi.minimumPressure = std::min(pi.minimumPressure, pj.pressure);
197 pj.minimumPressure = std::min(pj.minimumPressure, pi.pressure);
198 }
199 }
200 }
201}
double pressure
pressure of the particle
Definition particle.hpp:58
double minimumPressure
minimum pressure of the particle
Definition particle.hpp:64
Here is the caller graph for this function:

◆ calPressureGradient()

void MPS::calPressureGradient ( const double & re)
private

calculate pressure gradient term

Parameters
re

The pressure gradient term of the Navier-Stokes equation is calculated as

\[ -\frac{1}{\rho^0}\langle\nabla P\rangle_i = -\frac{1}{\rho^0}\frac{d}{n^0}\sum_{j\neq i} \frac{P_j-P'_i}{\|\mathbf{r}_{ij}\|^2}\mathbf{r}_{ij} w_{ij} \]

where \(P'_i\) is the minimum pressure of the particle \(i\).

Definition at line 203 of file mps.cpp.

203 {
204 double a = settings.dim / refValuesForGradient.n0;
205
206#pragma omp parallel for
207 for (auto& pi : particles) {
208 if (pi.type != ParticleType::Fluid)
209 continue;
210
211 Eigen::Vector3d grad = Eigen::Vector3d::Zero();
212 for (auto& neighbor : pi.neighbors) {
213 Particle& pj = particles[neighbor.id];
215 continue;
216
217 if (neighbor.distance < re) {
218 double w = weight(neighbor.distance, re);
219 // double dist2 = pow(neighbor.distance, 2);
220 double dist2 = (pj.position - pi.position).squaredNorm();
221 double pij = (pj.pressure - pi.minimumPressure) / dist2;
222 grad += (pj.position - pi.position) * pij * w;
223 }
224 }
225 grad *= a;
226 pi.acceleration -= grad / pi.density;
227 }
228}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ moveParticleUsingPressureGradient()

void MPS::moveParticleUsingPressureGradient ( )
private

move particles in correction step

The position and velocity of each particle are updated as

\[ \mathbf{u}_i^{k+1} = \mathbf{u}_i^* - \frac{1}{\rho^0} \langle\nabla P^{k+1} \rangle_i \Delta t. \]

Definition at line 230 of file mps.cpp.

230 {
231#pragma omp parallel for
232 for (auto&& p : particles) {
233 if (p.type == ParticleType::Fluid) {
234 p.velocity += p.acceleration * settings.dt;
235 p.position += p.acceleration * settings.dt * settings.dt;
236 }
237
238 p.acceleration.setZero();
239 }
240}
Here is the caller graph for this function:

◆ calCourant()

void MPS::calCourant ( )
private

calculate Courant number

Definition at line 242 of file mps.cpp.

242 {
243 courant = 0.0;
244
245 for (auto& pi : particles) {
246 if (pi.type != ParticleType::Fluid)
247 continue;
248
249 double iCourant = (pi.velocity.norm() * settings.dt) / settings.particleDistance;
250 courant = std::max(courant, iCourant);
251 }
252
254 cerr << "ERROR: Courant number is larger than CFL condition. Courant = " << courant << endl;
255 }
256}
double courant
Maximum courant number among all particles.
Definition mps.hpp:37
double cflCondition
CFL condition.
Definition settings.hpp:22
Here is the caller graph for this function:

Member Data Documentation

◆ settings

Settings MPS::settings

Settings for the simulation.

Definition at line 27 of file mps.hpp.

◆ gravity

Eigen::Vector3d MPS::gravity

Gravity vector for the simulation.

Definition at line 28 of file mps.hpp.

◆ refValuesForNumberDensity

RefValues MPS::refValuesForNumberDensity

Reference values for the simulation ( \(n^0\), \(\lambda^0\))

Definition at line 29 of file mps.hpp.

◆ refValuesForLaplacian

RefValues MPS::refValuesForLaplacian

Reference values for the simulation ( \(n^0\), \(\lambda^0\))

Definition at line 30 of file mps.hpp.

◆ refValuesForGradient

RefValues MPS::refValuesForGradient

Reference values for the simulation ( \(n^0\), \(\lambda^0\))

Definition at line 31 of file mps.hpp.

◆ particles

Particles MPS::particles

Particles in the simulation.

Definition at line 32 of file mps.hpp.

◆ domain

Domain MPS::domain {}

Domain of the simulation.

Definition at line 33 of file mps.hpp.

33{};

◆ pressureCalculator

std::unique_ptr<PressureCalculator::Interface> MPS::pressureCalculator

Interface for pressure calculation.

Definition at line 35 of file mps.hpp.

◆ courant

double MPS::courant {}

Maximum courant number among all particles.

Definition at line 37 of file mps.hpp.

37{};

◆ neighborSearcher

NeighborSearcher MPS::neighborSearcher
private

Neighbor searcher for neighbor search.

Definition at line 49 of file mps.hpp.

◆ surfaceDetector

std::unique_ptr<SurfaceDetector::Interface> MPS::surfaceDetector
private

Interface for free surface detection.

Definition at line 50 of file mps.hpp.


The documentation for this class was generated from the following files: