SPHinXsys  alpha version
fluid_dynamics_complex.hpp
Go to the documentation of this file.
1 
6 #pragma once
7 
9 
10 //=================================================================================================//
11 namespace SPH
12 {
13  //=================================================================================================//
14  namespace fluid_dynamics
15  {
16  //=================================================================================================//
17  template <class BaseRelaxationType>
18  template <class BaseBodyRelationType>
19  RelaxationWithWall<BaseRelaxationType>::
20  RelaxationWithWall(BaseBodyRelationType &base_body_relation,
21  BaseBodyRelationContact &wall_contact_relation)
22  : BaseRelaxationType(base_body_relation), FluidWallData(wall_contact_relation)
23  {
24  if (base_body_relation.sph_body_ != wall_contact_relation.sph_body_)
25  {
26  std::cout << "\n Error: the two body_relations do not have the same source body!" << std::endl;
27  std::cout << __FILE__ << ':' << __LINE__ << std::endl;
28  exit(1);
29  }
30 
31  for (size_t k = 0; k != FluidWallData::contact_particles_.size(); ++k)
32  {
33  Real rho0_k = FluidWallData::contact_particles_[k]->rho0_;
34  wall_inv_rho0_.push_back(1.0 / rho0_k);
35  wall_mass_.push_back(&(FluidWallData::contact_particles_[k]->mass_));
36  wall_Vol_.push_back(&(FluidWallData::contact_particles_[k]->Vol_));
37  wall_vel_ave_.push_back(FluidWallData::contact_particles_[k]->AverageVelocity());
38  wall_acc_ave_.push_back(FluidWallData::contact_particles_[k]->AverageAcceleration());
39  wall_n_.push_back(&(FluidWallData::contact_particles_[k]->n_));
40  }
41  }
42  //=================================================================================================//
43  template <class DensitySummationInnerType>
44  DensitySummation<DensitySummationInnerType>::
45  DensitySummation(BaseBodyRelationInner &inner_relation, BaseBodyRelationContact &contact_relation)
46  : ParticleDynamicsComplex<DensitySummationInnerType, FluidContactData>(inner_relation, contact_relation)
47  {
48  prepareContactData();
49  }
50  //=================================================================================================//
51  template <class DensitySummationInnerType>
52  DensitySummation<DensitySummationInnerType>::
53  DensitySummation(ComplexBodyRelation &complex_relation)
54  : DensitySummation(complex_relation.inner_relation_, complex_relation.contact_relation_) {}
55  //=================================================================================================//
56  template <class DensitySummationInnerType>
57  DensitySummation<DensitySummationInnerType>::
58  DensitySummation(ComplexBodyRelation &complex_relation, BaseBodyRelationContact &extra_contact_relation)
59  : ParticleDynamicsComplex<DensitySummationInnerType, FluidContactData>(complex_relation, extra_contact_relation)
60  {
61  prepareContactData();
62  }
63  //=================================================================================================//
64  template <class DensitySummationInnerType>
65  void DensitySummation<DensitySummationInnerType>::prepareContactData()
66  {
67  for (size_t k = 0; k != this->contact_particles_.size(); ++k)
68  {
69  Real rho0_k = this->contact_particles_[k]->rho0_;
70  contact_inv_rho0_.push_back(1.0 / rho0_k);
71  contact_mass_.push_back(&(this->contact_particles_[k]->mass_));
72  }
73  }
74  //=================================================================================================//
75  template <class DensitySummationInnerType>
77  {
78  DensitySummationInnerType::Interaction(index_i, dt);
79 
81  Real sigma(0.0);
82  Real inv_Vol_0_i = this->rho0_ / this->mass_[index_i];
83  for (size_t k = 0; k < this->contact_configuration_.size(); ++k)
84  {
85  StdLargeVec<Real> &contact_mass_k = *(this->contact_mass_[k]);
86  Real contact_inv_rho0_k = contact_inv_rho0_[k];
87  Neighborhood &contact_neighborhood = (*this->contact_configuration_[k])[index_i];
88  for (size_t n = 0; n != contact_neighborhood.current_size_; ++n)
89  {
90  sigma += contact_neighborhood.W_ij_[n] * inv_Vol_0_i * contact_inv_rho0_k * contact_mass_k[contact_neighborhood.j_[n]];
91  }
92  }
93  this->rho_sum_[index_i] += sigma * this->rho0_ * this->inv_sigma0_;
94  }
95  //=================================================================================================//
96  template <class BaseViscousAccelerationType>
97  template <class BaseBodyRelationType>
99  ViscousWithWall(BaseBodyRelationType &base_body_relation,
100  BaseBodyRelationContact &wall_contact_relation)
101  : RelaxationWithWall<BaseViscousAccelerationType>(base_body_relation, wall_contact_relation) {}
102  //=================================================================================================//
103  template <class BaseViscousAccelerationType>
104  void ViscousWithWall<BaseViscousAccelerationType>::Interaction(size_t index_i, Real dt)
105  {
106  BaseViscousAccelerationType::Interaction(index_i, dt);
107 
108  Real rho_i = this->rho_[index_i];
109  const Vecd &vel_i = this->vel_[index_i];
110 
111  Vecd acceleration(0), vel_derivative(0);
112  for (size_t k = 0; k < FluidWallData::contact_configuration_.size(); ++k)
113  {
114  StdLargeVec<Real> &Vol_k = *(this->wall_Vol_[k]);
115  StdLargeVec<Vecd> &vel_ave_k = *(this->wall_vel_ave_[k]);
116  Neighborhood &contact_neighborhood = (*FluidWallData::contact_configuration_[k])[index_i];
117  for (size_t n = 0; n != contact_neighborhood.current_size_; ++n)
118  {
119  size_t index_j = contact_neighborhood.j_[n];
120  Real r_ij = contact_neighborhood.r_ij_[n];
121 
122  vel_derivative = 2.0 * (vel_i - vel_ave_k[index_j]) / (r_ij + 0.01 * this->smoothing_length_);
123  acceleration += 2.0 * this->mu_ * vel_derivative * contact_neighborhood.dW_ij_[n] * Vol_k[index_j] / rho_i;
124  }
125  }
126 
127  this->acc_prior_[index_i] += acceleration;
128  }
129  //=================================================================================================//
130  template <class BaseViscousAccelerationType>
131  BaseViscousAccelerationWithWall<BaseViscousAccelerationType>::
132  BaseViscousAccelerationWithWall(ComplexBodyRelation &fluid_wall_relation)
133  : BaseViscousAccelerationType(fluid_wall_relation.inner_relation_,
134  fluid_wall_relation.contact_relation_) {}
135  //=================================================================================================//
136  template <class BaseViscousAccelerationType>
137  BaseViscousAccelerationWithWall<BaseViscousAccelerationType>::
138  BaseViscousAccelerationWithWall(BaseBodyRelationInner &fluid_inner_relation,
139  BaseBodyRelationContact &wall_contact_relation)
140  : BaseViscousAccelerationType(fluid_inner_relation, wall_contact_relation) {}
141  //=================================================================================================//
142  template <class BaseViscousAccelerationType>
143  BaseViscousAccelerationWithWall<BaseViscousAccelerationType>::
144  BaseViscousAccelerationWithWall(ComplexBodyRelation &fluid_complex_relation,
145  BaseBodyRelationContact &wall_contact_relation)
146  : BaseViscousAccelerationType(fluid_complex_relation, wall_contact_relation) {}
147  //=================================================================================================//
148  template <class BasePressureRelaxationType>
149  template <class BaseBodyRelationType>
150  PressureRelaxation<BasePressureRelaxationType>::
151  PressureRelaxation(BaseBodyRelationType &base_body_relation,
152  BaseBodyRelationContact &wall_contact_relation)
153  : RelaxationWithWall<BasePressureRelaxationType>(base_body_relation, wall_contact_relation) {}
154  //=================================================================================================//
155  template <class BasePressureRelaxationType>
156  void PressureRelaxation<BasePressureRelaxationType>::Interaction(size_t index_i, Real dt)
157  {
158  BasePressureRelaxationType::Interaction(index_i, dt);
159 
160  FluidState state_i(this->rho_[index_i], this->vel_[index_i], this->p_[index_i]);
161  Vecd acc_prior_i = computeNonConservativeAcceleration(index_i);
162 
163  Vecd acceleration(0.0);
164  for (size_t k = 0; k < FluidWallData::contact_configuration_.size(); ++k)
165  {
166  StdLargeVec<Real> &Vol_k = *(this->wall_Vol_[k]);
167  StdLargeVec<Vecd> &vel_ave_k = *(this->wall_vel_ave_[k]);
168  StdLargeVec<Vecd> &acc_ave_k = *(this->wall_acc_ave_[k]);
169  StdLargeVec<Vecd> &n_k = *(this->wall_n_[k]);
170  Neighborhood &wall_neighborhood = (*FluidWallData::contact_configuration_[k])[index_i];
171  for (size_t n = 0; n != wall_neighborhood.current_size_; ++n)
172  {
173  size_t index_j = wall_neighborhood.j_[n];
174  Vecd &e_ij = wall_neighborhood.e_ij_[n];
175  Real dW_ij = wall_neighborhood.dW_ij_[n];
176  Real r_ij = wall_neighborhood.r_ij_[n];
177 
178  Real face_wall_external_acceleration = dot((acc_prior_i - acc_ave_k[index_j]), -e_ij);
179  Vecd vel_in_wall = 2.0 * vel_ave_k[index_j] - state_i.vel_;
180  Real p_in_wall = state_i.p_ + state_i.rho_ * r_ij * SMAX(0.0, face_wall_external_acceleration);
181  Real rho_in_wall = this->material_->DensityFromPressure(p_in_wall);
182  FluidState state_j(rho_in_wall, vel_in_wall, p_in_wall);
183  Real p_star = this->riemann_solver_.getPStar(state_i, state_j, n_k[index_j]);
184  acceleration -= 2.0 * p_star * e_ij * Vol_k[index_j] * dW_ij / state_i.rho_;
185  }
186  }
187  this->acc_[index_i] += acceleration;
188  }
189  //=================================================================================================//
190  template <class BasePressureRelaxationType>
191  Vecd PressureRelaxation<BasePressureRelaxationType>::computeNonConservativeAcceleration(size_t index_i)
192  {
193  return this->acc_prior_[index_i];
194  }
195  //=================================================================================================//
196  template <class BasePressureRelaxationType>
197  template <class BaseBodyRelationType>
198  ExtendPressureRelaxation<BasePressureRelaxationType>::
199  ExtendPressureRelaxation(BaseBodyRelationType &base_body_relation,
200  BaseBodyRelationContact &wall_contact_relation, Real penalty_strength)
201  : PressureRelaxation<BasePressureRelaxationType>(base_body_relation, wall_contact_relation),
202  penalty_strength_(penalty_strength)
203  {
204  this->particles_->registerVariable(non_cnsrv_acc_, "NonConservativeAcceleration");
205  }
206  //=================================================================================================//
207  template <class BasePressureRelaxationType>
208  void ExtendPressureRelaxation<BasePressureRelaxationType>::Initialization(size_t index_i, Real dt)
209  {
210  BasePressureRelaxationType::Initialization(index_i, dt);
211  non_cnsrv_acc_[index_i] = Vecd(0);
212  }
213  //=================================================================================================//
214  template <class BasePressureRelaxationType>
216  {
218 
219  Real rho_i = this->rho_[index_i];
220  Real penalty_pressure = this->p_[index_i];
221  Vecd acceleration(0);
222  for (size_t k = 0; k < FluidWallData::contact_configuration_.size(); ++k)
223  {
224  Real particle_spacing_j1 = 1.0 / FluidWallData::contact_bodies_[k]->sph_adaptation_->ReferenceSpacing();
225  Real particle_spacing_ratio2 = 1.0 / (this->body_->sph_adaptation_->ReferenceSpacing() * particle_spacing_j1);
226  particle_spacing_ratio2 *= 0.1 * particle_spacing_ratio2;
227 
228  StdLargeVec<Real> &Vol_k = *(this->wall_Vol_[k]);
229  StdLargeVec<Vecd> &n_k = *(this->wall_n_[k]);
230  Neighborhood &wall_neighborhood = (*FluidWallData::contact_configuration_[k])[index_i];
231  for (size_t n = 0; n != wall_neighborhood.current_size_; ++n)
232  {
233  size_t index_j = wall_neighborhood.j_[n];
234  Vecd &e_ij = wall_neighborhood.e_ij_[n];
235  Real dW_ij = wall_neighborhood.dW_ij_[n];
236  Real r_ij = wall_neighborhood.r_ij_[n];
237  Vecd &n_j = n_k[index_j];
238 
240  Real projection = dot(e_ij, n_j);
241  Real delta = 2.0 * projection * r_ij * particle_spacing_j1;
242  Real beta = delta < 1.0 ? (1.0 - delta) * (1.0 - delta) * particle_spacing_ratio2 : 0.0;
243  //penalty must be positive so that the penalty force is pointed to fluid inner domain
244  Real penalty = penalty_strength_ * beta * fabs(projection * penalty_pressure);
245 
246  //penalty force induced acceleration
247  acceleration -= 2.0 * penalty * n_j * Vol_k[index_j] * dW_ij / rho_i;
248  }
249  }
250  this->acc_[index_i] += acceleration;
251  }
252  //=================================================================================================//
253  template <class BasePressureRelaxationType>
256  {
257  Vecd acceleration = BasePressureRelaxationType::computeNonConservativeAcceleration(index_i);
258  non_cnsrv_acc_[index_i] = acceleration;
259  return acceleration;
260  }
261  //=================================================================================================//
262  template <class BasePressureRelaxationType>
263  BasePressureRelaxationWithWall<BasePressureRelaxationType>::
264  BasePressureRelaxationWithWall(ComplexBodyRelation &fluid_wall_relation)
265  : BasePressureRelaxationType(fluid_wall_relation.inner_relation_,
266  fluid_wall_relation.contact_relation_) {}
267  //=================================================================================================//
268  template <class BasePressureRelaxationType>
269  BasePressureRelaxationWithWall<BasePressureRelaxationType>::
270  BasePressureRelaxationWithWall(BaseBodyRelationInner &fluid_inner_relation,
271  BaseBodyRelationContact &wall_contact_relation)
272  : BasePressureRelaxationType(fluid_inner_relation,
273  wall_contact_relation) {}
274  //=================================================================================================//
275  template <class BasePressureRelaxationType>
276  BasePressureRelaxationWithWall<BasePressureRelaxationType>::
277  BasePressureRelaxationWithWall(ComplexBodyRelation &fluid_complex_relation,
278  BaseBodyRelationContact &wall_contact_relation)
279  : BasePressureRelaxationType(fluid_complex_relation,
280  wall_contact_relation) {}
281  //=================================================================================================//
282  template <class BasePressureRelaxationType>
283  ExtendPressureRelaxationWithWall<BasePressureRelaxationType>::
284  ExtendPressureRelaxationWithWall(ComplexBodyRelation &fluid_wall_relation, Real penalty_strength)
285  : BasePressureRelaxationType(fluid_wall_relation.inner_relation_,
286  fluid_wall_relation.contact_relation_, penalty_strength) {}
287  //=================================================================================================//
288  template <class BasePressureRelaxationType>
289  ExtendPressureRelaxationWithWall<BasePressureRelaxationType>::
290  ExtendPressureRelaxationWithWall(BaseBodyRelationInner &fluid_inner_relation,
291  BaseBodyRelationContact &wall_contact_relation, Real penalty_strength)
292  : BasePressureRelaxationType(fluid_inner_relation,
293  wall_contact_relation, penalty_strength) {}
294  //=================================================================================================//
295  template <class BasePressureRelaxationType>
296  ExtendPressureRelaxationWithWall<BasePressureRelaxationType>::
297  ExtendPressureRelaxationWithWall(ComplexBodyRelation &fluid_complex_relation,
298  BaseBodyRelationContact &wall_contact_relation, Real penalty_strength)
299  : BasePressureRelaxationType(fluid_complex_relation,
300  wall_contact_relation, penalty_strength) {}
301  //=================================================================================================//
302  template <class BaseDensityRelaxationType>
303  template <class BaseBodyRelationType>
305  DensityRelaxation(BaseBodyRelationType &base_body_relation,
306  BaseBodyRelationContact &wall_contact_relation)
307  : RelaxationWithWall<BaseDensityRelaxationType>(base_body_relation, wall_contact_relation) {}
308  //=================================================================================================//
309  template <class BaseDensityRelaxationType>
311  {
312  BaseDensityRelaxationType::Interaction(index_i, dt);
313 
314  FluidState state_i(this->rho_[index_i], this->vel_[index_i], this->p_[index_i]);
315  Real density_change_rate = 0.0;
316  for (size_t k = 0; k < FluidWallData::contact_configuration_.size(); ++k)
317  {
318  Vecd &acc_prior_i = this->acc_prior_[index_i];
319 
320  StdLargeVec<Real> &Vol_k = *(this->wall_Vol_[k]);
321  StdLargeVec<Vecd> &vel_ave_k = *(this->wall_vel_ave_[k]);
322  StdLargeVec<Vecd> &acc_ave_k = *(this->wall_acc_ave_[k]);
323  StdLargeVec<Vecd> &n_k = *(this->wall_n_[k]);
324  Neighborhood &wall_neighborhood = (*FluidWallData::contact_configuration_[k])[index_i];
325  for (size_t n = 0; n != wall_neighborhood.current_size_; ++n)
326  {
327  size_t index_j = wall_neighborhood.j_[n];
328  Vecd &e_ij = wall_neighborhood.e_ij_[n];
329  Real r_ij = wall_neighborhood.r_ij_[n];
330  Real dW_ij = wall_neighborhood.dW_ij_[n];
331 
332  Real face_wall_external_acceleration = dot((acc_prior_i - acc_ave_k[index_j]), -e_ij);
333  Vecd vel_in_wall = 2.0 * vel_ave_k[index_j] - state_i.vel_;
334  Real p_in_wall = state_i.p_ + state_i.rho_ * r_ij * SMAX(0.0, face_wall_external_acceleration);
335  Real rho_in_wall = this->material_->DensityFromPressure(p_in_wall);
336  FluidState state_j(rho_in_wall, vel_in_wall, p_in_wall);
337  Vecd vel_star = this->riemann_solver_.getVStar(state_i, state_j, n_k[index_j]);
338  density_change_rate += 2.0 * state_i.rho_ * Vol_k[index_j] * dot(state_i.vel_ - vel_star, e_ij) * dW_ij;
339  }
340  }
341  this->drho_dt_[index_i] += density_change_rate;
342  }
343  //=================================================================================================//
344  template <class BaseDensityRelaxationType>
345  BaseDensityRelaxationWithWall<BaseDensityRelaxationType>::
346  BaseDensityRelaxationWithWall(ComplexBodyRelation &fluid_wall_relation)
347  : DensityRelaxation<BaseDensityRelaxationType>(fluid_wall_relation.inner_relation_,
348  fluid_wall_relation.contact_relation_) {}
349  //=================================================================================================//
350  template <class BaseDensityRelaxationType>
351  BaseDensityRelaxationWithWall<BaseDensityRelaxationType>::
352  BaseDensityRelaxationWithWall(BaseBodyRelationInner &fluid_inner_relation,
353  BaseBodyRelationContact &wall_contact_relation)
354  : DensityRelaxation<BaseDensityRelaxationType>(fluid_inner_relation,
355  wall_contact_relation) {}
356  //=================================================================================================//
357  template <class BaseDensityRelaxationType>
358  BaseDensityRelaxationWithWall<BaseDensityRelaxationType>::
359  BaseDensityRelaxationWithWall(ComplexBodyRelation &fluid_complex_relation,
360  BaseBodyRelationContact &wall_contact_relation)
361  : DensityRelaxation<BaseDensityRelaxationType>(fluid_complex_relation, wall_contact_relation) {}
362  //=================================================================================================//
363  }
364  //=================================================================================================//
365 }
366 //=================================================================================================//
A neighborhood around particle i.
Definition: neighbor_relation.h:47
The base relation between a SPH body and its contact SPH bodies.
Definition: base_body_relation.h:136
size_t current_size_
Definition: neighbor_relation.h:50
template density relaxation scheme without using different Riemann solvers. The difference from the f...
StdLargeVec< Real > r_ij_
Definition: neighbor_relation.h:56
StdLargeVec< Vecd > e_ij_
Definition: neighbor_relation.h:57
StdVec< ParticleConfiguration * > contact_configuration_
Definition: base_particle_dynamics.h:251
StdLargeVec< Real > W_ij_
Definition: neighbor_relation.h:54
template class pressure relaxation scheme with wall boundary
Definition: fluid_dynamics_complex.h:153
virtual void Interaction(size_t index_i, Real dt=0.0) override
Definition: fluid_dynamics_complex.hpp:76
StdLargeVec< Real > dW_ij_
Definition: neighbor_relation.h:55
The relation combined an inner and a contact body relation. The interaction is in a inner-boundary-co...
Definition: complex_body_relation.h:42
template class for pressure relaxation scheme with wall boundary and considering non-conservative acc...
Definition: fluid_dynamics_complex.h:174
virtual void Interaction(size_t index_i, Real dt=0.0) override
Definition: fluid_dynamics_complex.hpp:215
Abstract base class for general relaxation algorithms with wall.
Definition: fluid_dynamics_complex.h:57
template class viscous acceleration with wall boundary
Definition: fluid_dynamics_complex.h:99
Here, we define the algorithm classes for complex fluid dynamics, which is involving with either soli...
StdLargeVec< size_t > j_
Definition: neighbor_relation.h:53
Definition: solid_body_supplementary.cpp:9