SPHinXsys  alpha version
fluid_structure_interaction.h
Go to the documentation of this file.
1 /* -------------------------------------------------------------------------*
2 * SPHinXsys *
3 * --------------------------------------------------------------------------*
4 * SPHinXsys (pronunciation: s'finksis) is an acronym from Smoothed Particle *
5 * Hydrodynamics for industrial compleX systems. It provides C++ APIs for *
6 * physical accurate simulation and aims to model coupled industrial dynamic *
7 * systems including fluid, solid, multi-body dynamics and beyond with SPH *
8 * (smoothed particle hydrodynamics), a meshless computational method using *
9 * particle discretization. *
10 * *
11 * SPHinXsys is partially funded by German Research Foundation *
12 * (Deutsche Forschungsgemeinschaft) DFG HU1527/6-1, HU1527/10-1 *
13 * and HU1527/12-1. *
14 * *
15 * Portions copyright (c) 2017-2020 Technical University of Munich and *
16 * the authors' affiliations. *
17 * *
18 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
19 * not use this file except in compliance with the License. You may obtain a *
20 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
21 * *
22 * --------------------------------------------------------------------------*/
29 #ifndef FLUID_STRUCTURE_INTERACTION_H
30 #define FLUID_STRUCTURE_INTERACTION_H
31 
32 #include "all_particle_dynamics.h"
33 #include "base_material.h"
34 #include "fluid_dynamics_complex.h"
35 #include "elastic_dynamics.h"
36 #include "riemann_solver.h"
37 
38 namespace SPH
39 {
40  namespace solid_dynamics
41  {
42  typedef DataDelegateSimple<SolidBody, SolidParticles, Solid> SolidDataSimple;
43  typedef DataDelegateContact<SolidBody, SolidParticles, Solid, FluidBody, FluidParticles, Fluid> FSIContactData;
44  typedef DataDelegateContact<SolidBody, SolidParticles, Solid, EulerianFluidBody,
45  FluidParticles, Fluid> EFSIContactData; //EFSIContactData=Eulerian Fluid contact Data
46 
52  {
53  public:
54  explicit FluidViscousForceOnSolid(BaseBodyRelationContact &contact_relation);
55  virtual ~FluidViscousForceOnSolid(){};
56 
57  protected:
58  StdLargeVec<Real> &Vol_;
59  StdLargeVec<Vecd> &vel_ave_;
60  StdVec<StdLargeVec<Real> *> contact_Vol_, contact_rho_n_;
61  StdVec<StdLargeVec<Vecd> *> contact_vel_n_;
62  StdVec<Real> mu_;
63  StdVec<Real> smoothing_length_;
64  StdLargeVec<Vecd> viscous_force_from_fluid_;
65 
66  virtual void Interaction(size_t index_i, Real dt = 0.0) override;
67  };
68 
74  {
75  public:
76  explicit FluidViscousForceOnSolidInEuler(BaseBodyRelationContact &contact_relation);
78 
79  protected:
80  StdLargeVec<Real> &Vol_;
81  StdLargeVec<Vecd> &vel_ave_;
82  StdVec<StdLargeVec<Real> *> contact_Vol_, contact_rho_n_;
83  StdVec<StdLargeVec<Vecd> *> contact_vel_n_;
84  StdVec<Real> mu_;
85  StdVec<Real> smoothing_length_;
86  StdLargeVec<Vecd> viscous_force_from_fluid_;
87 
88  virtual void Interaction(size_t index_i, Real dt = 0.0) override;
89  };
90 
96  {
97  public:
99  : FluidViscousForceOnSolid(contact_relation){};
101 
102  protected:
103  virtual void Interaction(size_t index_i, Real dt = 0.0) override;
104  };
105 
113  template <class RiemannSolverType>
115  {
116  public:
117  explicit BaseFluidPressureForceOnSolid(BaseBodyRelationContact &contact_relation)
118  : InteractionDynamics(*contact_relation.sph_body_),
119  FSIContactData(contact_relation),
120  Vol_(particles_->Vol_), vel_ave_(*particles_->AverageVelocity()),
121  acc_prior_(particles_->acc_prior_),
122  acc_ave_(*particles_->AverageAcceleration()), n_(particles_->n_)
123  {
124  particles_->registerVariable(force_from_fluid_, "ForceFromFluid");
125  for (size_t k = 0; k != contact_particles_.size(); ++k)
126  {
127  contact_Vol_.push_back(&(contact_particles_[k]->Vol_));
128  contact_rho_n_.push_back(&(contact_particles_[k]->rho_));
129  contact_vel_n_.push_back(&(contact_particles_[k]->vel_));
130  contact_p_.push_back(&(contact_particles_[k]->p_));
131  contact_acc_prior_.push_back(&(contact_particles_[k]->acc_prior_));
132  riemann_solvers_.push_back(RiemannSolverType(*contact_material_[k], *contact_material_[k]));
133  }
134  };
135  virtual ~BaseFluidPressureForceOnSolid(){};
136 
137  protected:
138  StdLargeVec<Real> &Vol_;
139  StdLargeVec<Vecd> &vel_ave_, &acc_prior_, &acc_ave_, &n_;
140  StdVec<StdLargeVec<Real> *> contact_Vol_, contact_rho_n_, contact_p_;
141  StdVec<StdLargeVec<Vecd> *> contact_vel_n_, contact_acc_prior_;
142  StdVec<RiemannSolverType> riemann_solvers_;
145  virtual void Interaction(size_t index_i, Real dt = 0.0) override
146  {
147  const Vecd &acc_ave_i = acc_ave_[index_i];
148  Real Vol_i = Vol_[index_i];
149  const Vecd &vel_ave_i = vel_ave_[index_i];
150  const Vecd &n_i = n_[index_i];
151 
152  Vecd force(0);
153  for (size_t k = 0; k < contact_configuration_.size(); ++k)
154  {
155  StdLargeVec<Real> &Vol_k = *(contact_Vol_[k]);
156  StdLargeVec<Real> &rho_n_k = *(contact_rho_n_[k]);
157  StdLargeVec<Real> &p_k = *(contact_p_[k]);
158  StdLargeVec<Vecd> &vel_n_k = *(contact_vel_n_[k]);
159  StdLargeVec<Vecd> &acc_prior_k = *(contact_acc_prior_[k]);
160  Fluid *fluid_k = contact_material_[k];
161  RiemannSolverType &riemann_solver_k = riemann_solvers_[k];
162  Neighborhood &contact_neighborhood = (*contact_configuration_[k])[index_i];
163  for (size_t n = 0; n != contact_neighborhood.current_size_; ++n)
164  {
165  size_t index_j = contact_neighborhood.j_[n];
166  Vecd e_ij = contact_neighborhood.e_ij_[n];
167  Real r_ij = contact_neighborhood.r_ij_[n];
168  Real face_wall_external_acceleration = dot((acc_prior_k[index_j] - acc_ave_i), e_ij);
169  Real p_in_wall = p_k[index_j] + rho_n_k[index_j] * r_ij * SMAX(0.0, face_wall_external_acceleration);
170  Real rho_in_wall = fluid_k->DensityFromPressure(p_in_wall);
171  Vecd vel_in_wall = 2.0 * vel_ave_i - vel_n_k[index_j];
172 
173  FluidState state_l(rho_n_k[index_j], vel_n_k[index_j], p_k[index_j]);
174  FluidState state_r(rho_in_wall, vel_in_wall, p_in_wall);
175  Real p_star = riemann_solver_k.getPStar(state_l, state_r, n_i);
176  force -= 2.0 * p_star * e_ij * Vol_i * Vol_k[index_j] * contact_neighborhood.dW_ij_[n];
177  }
178  }
179  force_from_fluid_[index_i] = force;
180  acc_prior_[index_i] = force / particles_->ParticleMass(index_i);
181  };
182  };
183  using FluidPressureForceOnSolid = BaseFluidPressureForceOnSolid<NoRiemannSolver>;
184  using FluidPressureForceOnSolidRiemann = BaseFluidPressureForceOnSolid<AcousticRiemannSolver>;
185 
193  template <class RiemannSolverType>
195  {
196  public:
198  : InteractionDynamics(*contact_relation.sph_body_),
199  EFSIContactData(contact_relation),
200  Vol_(particles_->Vol_), vel_ave_(*particles_->AverageVelocity()),
201  acc_prior_(particles_->acc_prior_), n_(particles_->n_)
202  {
203  particles_->registerVariable(force_from_fluid_, "ForceFromFluid");
204  for (size_t k = 0; k != contact_particles_.size(); ++k)
205  {
206  contact_Vol_.push_back(&(contact_particles_[k]->Vol_));
207  contact_rho_n_.push_back(&(contact_particles_[k]->rho_));
208  contact_vel_n_.push_back(&(contact_particles_[k]->vel_));
209  contact_p_.push_back(&(contact_particles_[k]->p_));
210  riemann_solvers_.push_back(RiemannSolverType(*contact_material_[k], *contact_material_[k]));
211  }
212  };
214 
215  protected:
216  StdLargeVec<Real> &Vol_;
217  StdLargeVec<Vecd> &vel_ave_, &acc_prior_, &n_;
218  StdVec<StdLargeVec<Real> *> contact_Vol_, contact_rho_n_, contact_p_;
219  StdVec<StdLargeVec<Vecd> *> contact_vel_n_;
220  StdVec<RiemannSolverType> riemann_solvers_;
223  virtual void Interaction(size_t index_i, Real dt = 0.0) override
224  {
225  Real Vol_i = Vol_[index_i];
226  const Vecd &vel_ave_i = vel_ave_[index_i];
227  const Vecd &n_i = n_[index_i];
228 
229  Vecd force(0);
230  for (size_t k = 0; k < contact_configuration_.size(); ++k)
231  {
232  StdLargeVec<Real> &Vol_k = *(contact_Vol_[k]);
233  StdLargeVec<Real> &rho_n_k = *(contact_rho_n_[k]);
234  StdLargeVec<Real> &p_k = *(contact_p_[k]);
235  StdLargeVec<Vecd> &vel_n_k = *(contact_vel_n_[k]);
236  Fluid *fluid_k = contact_material_[k];
237  RiemannSolverType &riemann_solver_k = riemann_solvers_[k];
238  Neighborhood &contact_neighborhood = (*contact_configuration_[k])[index_i];
239  for (size_t n = 0; n != contact_neighborhood.current_size_; ++n)
240  {
241  size_t index_j = contact_neighborhood.j_[n];
242  Vecd e_ij = contact_neighborhood.e_ij_[n];
243  Real r_ij = contact_neighborhood.r_ij_[n];
244  Real p_in_wall = p_k[index_j];
245  Real rho_in_wall = fluid_k->DensityFromPressure(p_in_wall);
246  Vecd vel_in_wall = - vel_n_k[index_j];
247 
248  FluidState state_l(rho_n_k[index_j], vel_n_k[index_j], p_k[index_j]);
249  FluidState state_r(rho_in_wall, vel_in_wall, p_in_wall);
250  FluidState interface_state = riemann_solver_k.getInterfaceState(state_l, state_r, n_i);
251  Real p_star = interface_state.p_;
252  force -= 2.0 * p_star * e_ij * Vol_i * Vol_k[index_j] * contact_neighborhood.dW_ij_[n];
253  }
254  }
255  force_from_fluid_[index_i] = force;
256  acc_prior_[index_i] = force / particles_->ParticleMass(index_i);
257  };
258  };
259  using FluidPressureForceOnSolidInEuler = BaseFluidPressureForceOnSolidInEuler<NoRiemannSolver>;
260  using FluidPressureForceOnSolidAcousticRiemannInEuler = BaseFluidPressureForceOnSolidInEuler<AcousticRiemannSolver>;
261  using FluidPressureForceOnSolidHLLCRiemannInEuler = BaseFluidPressureForceOnSolidInEuler<HLLCRiemannSolverInWeaklyCompressibleFluid>;
262  using FluidPressureForceOnSolidHLLCWithLimiterRiemannInEuler = BaseFluidPressureForceOnSolidInEuler<HLLCRiemannSolverWithLimiterInWeaklyCompressibleFluid>;
263 
268  template <class PressureForceType, class ViscousForceType>
270  {
271  public:
272  explicit BaseFluidForceOnSolidUpdate(BaseBodyRelationContact &contact_relation)
273  : PressureForceType(contact_relation), viscous_force_(contact_relation),
274  viscous_force_from_fluid_(*this->particles_->template getVariableByName<Vecd>("ViscousForceFromFluid")){};
275  virtual ~BaseFluidForceOnSolidUpdate(){};
276 
277  ViscousForceType viscous_force_;
278 
279  protected:
280  StdLargeVec<Vecd> &viscous_force_from_fluid_;
281 
282  virtual void Interaction(size_t index_i, Real dt = 0.0) override
283  {
284  PressureForceType::Interaction(index_i, dt);
285  this->force_from_fluid_[index_i] += viscous_force_from_fluid_[index_i];
286  this->acc_prior_[index_i] += viscous_force_from_fluid_[index_i] / this->particles_->ParticleMass(index_i);
287  };
288  };
297 
298 
303  class TotalViscousForceOnSolid : public ParticleDynamicsReduce<Vecd, ReduceSum<Vecd>>, public SolidDataSimple
304  {
305  public:
306  explicit TotalViscousForceOnSolid(SolidBody &solid_body);
307  virtual ~TotalViscousForceOnSolid(){};
308 
309  protected:
310  StdLargeVec<Vecd> &viscous_force_from_fluid_;
311  Vecd ReduceFunction(size_t index_i, Real dt = 0.0) override;
312  };
313 
318  class TotalForceOnSolid : public ParticleDynamicsReduce<Vecd, ReduceSum<Vecd>>, public SolidDataSimple
319  {
320  public:
321  explicit TotalForceOnSolid(SolidBody &solid_body);
322  virtual ~TotalForceOnSolid(){};
323 
324  protected:
325  StdLargeVec<Vecd> &force_from_fluid_;
326  Vecd ReduceFunction(size_t index_i, Real dt = 0.0) override;
327  };
328 
336  {
337  public:
338  explicit InitializeDisplacement(SolidBody &solid_body, StdLargeVec<Vecd> &pos_temp);
339  virtual ~InitializeDisplacement(){};
340 
341  protected:
342  StdLargeVec<Vecd> &pos_temp_, &pos_, &vel_ave_, &acc_ave_;
343  virtual void Update(size_t index_i, Real dt = 0.0) override;
344  };
345 
353  {
354  public:
355  explicit UpdateAverageVelocityAndAcceleration(SolidBody &solid_body, StdLargeVec<Vecd> &pos_temp)
356  : InitializeDisplacement(solid_body, pos_temp){};
358 
359  protected:
360  virtual void Update(size_t index_i, Real dt = 0.0) override;
361  };
362 
370  {
371  protected:
372  StdLargeVec<Vecd> pos_temp_;
373 
374  public:
375  InitializeDisplacement initialize_displacement_;
376  UpdateAverageVelocityAndAcceleration update_averages_;
377 
378  explicit AverageVelocityAndAcceleration(SolidBody &solid_body);
380  };
381  }
382 }
383 #endif //FLUID_STRUCTURE_INTERACTION_H
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
Definition: fluid_structure_interaction.h:114
virtual void Interaction(size_t index_i, Real dt=0.0) override
Definition: fluid_structure_interaction.cpp:107
size_t current_size_
Definition: neighbor_relation.h:50
Simple particle dynamics without considering particle interaction.
Definition: particle_dynamics_algorithms.h:48
Declaration of solidbody which is used for Solid BCs and derived from RealBody.
Definition: solid_body.h:46
StdLargeVec< Real > r_ij_
Definition: neighbor_relation.h:56
Base class of all fluids.
Definition: base_material.h:89
StdLargeVec< Vecd > e_ij_
Definition: neighbor_relation.h:57
virtual void Interaction(size_t index_i, Real dt=0.0) override
Definition: fluid_structure_interaction.cpp:31
StdVec< ParticleConfiguration * > contact_configuration_
Definition: base_particle_dynamics.h:251
Base abstract class for reduce.
Definition: particle_dynamics_algorithms.h:69
This is the base classes of all materials. A function in a derived material class returns a value wit...
template class for computing force from fluid with updated viscous force
Definition: fluid_structure_interaction.h:269
Computing average velocity. This class is for FSI applications to achieve smaller solid dynamics time...
Definition: fluid_structure_interaction.h:352
Impose force matching between fluid and solid dynamics. Note that the fluid time step should be large...
Definition: fluid_structure_interaction.h:369
initialize the displacement for computing average velocity. This class is for FSI applications to ach...
Definition: fluid_structure_interaction.h:335
Template class fro computing the pressure force from the fluid with different Riemann solvers...
Definition: fluid_structure_interaction.h:194
Computing the viscous force from the fluid.
Definition: fluid_structure_interaction.h:51
prepare data for contact particle dynamics
Definition: base_particle_dynamics.h:240
Here, we define the algorithm classes for elastic solid dynamics.
Computing the total viscous force from fluid.
Definition: fluid_structure_interaction.h:303
StdLargeVec< Real > dW_ij_
Definition: neighbor_relation.h:55
Computing the viscous force from the fluid in eulerian framework.
Definition: fluid_structure_interaction.h:73
Computing total force from fluid.
Definition: fluid_structure_interaction.h:318
Computing the viscous force from the fluid.
Definition: fluid_structure_interaction.h:95
This is the class for particle interaction with other particles.
Definition: particle_dynamics_algorithms.h:115
virtual void Interaction(size_t index_i, Real dt=0.0) override
Definition: fluid_structure_interaction.cpp:78
StdLargeVec< Vecd > force_from_fluid_
Definition: fluid_structure_interaction.h:221
StdLargeVec< Vecd > force_from_fluid_
Definition: fluid_structure_interaction.h:143
Here, we define the algorithm classes for complex fluid dynamics, which is involving with either soli...
prepare data for simple particle dynamics.
Definition: base_particle_dynamics.h:185
StdLargeVec< size_t > j_
Definition: neighbor_relation.h:53
Definition: riemann_solver.h:36
Definition: solid_body_supplementary.cpp:9